diff options
author | Vincent <vinsteimes@gmail.com> | 2020-10-22 02:33:40 +0200 |
---|---|---|
committer | Vincent <vinsteimes@gmail.com> | 2020-12-03 17:51:43 +0100 |
commit | 704d6de84ce110ec5c7eb32c5968b35d6bdcde39 (patch) | |
tree | 7b08959ec949490e47c6d33e77dc978f1e48cb5e /modules/minimp3 | |
parent | ea7dd1be36abc528f39e7c42725267d01774983b (diff) |
add mp3 import and playback support
Diffstat (limited to 'modules/minimp3')
-rw-r--r-- | modules/minimp3/SCsub | 17 | ||||
-rw-r--r-- | modules/minimp3/audio_stream_mp3.cpp | 228 | ||||
-rw-r--r-- | modules/minimp3/audio_stream_mp3.h | 110 | ||||
-rw-r--r-- | modules/minimp3/config.py | 16 | ||||
-rw-r--r-- | modules/minimp3/doc_classes/AudioStreamMP3.xml | 26 | ||||
-rw-r--r-- | modules/minimp3/register_types.cpp | 52 | ||||
-rw-r--r-- | modules/minimp3/register_types.h | 37 | ||||
-rw-r--r-- | modules/minimp3/resource_importer_mp3.cpp | 104 | ||||
-rw-r--r-- | modules/minimp3/resource_importer_mp3.h | 58 |
9 files changed, 648 insertions, 0 deletions
diff --git a/modules/minimp3/SCsub b/modules/minimp3/SCsub new file mode 100644 index 0000000000..f4d1605d55 --- /dev/null +++ b/modules/minimp3/SCsub @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +env_minimp3 = env_modules.Clone() + +thirdparty_dir = "#thirdparty/minimp3/" + +# Treat minimp3 headers as system headers to avoid raising warnings. Not supported on MSVC. +if not env.msvc: + env_minimp3.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path]) +else: + env_minimp3.Prepend(CPPPATH=[thirdparty_dir]) + +# Godot's own source files +env_minimp3.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/minimp3/audio_stream_mp3.cpp b/modules/minimp3/audio_stream_mp3.cpp new file mode 100644 index 0000000000..b20c043e0c --- /dev/null +++ b/modules/minimp3/audio_stream_mp3.cpp @@ -0,0 +1,228 @@ +/*************************************************************************/ +/* audio_stream_mp3.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#define MINIMP3_ONLY_MP3 +#define MINIMP3_FLOAT_OUTPUT +#define MINIMP3_IMPLEMENTATION +#define MINIMP3_NO_STDIO + +#include "audio_stream_mp3.h" + +#include "core/os/file_access.h" + +void AudioStreamPlaybackMP3::_mix_internal(AudioFrame *p_buffer, int p_frames) { + ERR_FAIL_COND(!active); + + int todo = p_frames; + + while (todo && active) { + mp3dec_frame_info_t frame_info; + mp3d_sample_t *buf_frame = nullptr; + + int samples_mixed = mp3dec_ex_read_frame(mp3d, &buf_frame, &frame_info, mp3_stream->channels); + + if (samples_mixed) { + p_buffer[p_frames - todo] = AudioFrame(buf_frame[0], buf_frame[samples_mixed - 1]); + --todo; + ++frames_mixed; + } + + else { + //EOF + if (mp3_stream->loop) { + seek(mp3_stream->loop_offset); + loops++; + } else { + //fill remainder with silence + for (int i = p_frames - todo; i < p_frames; i++) { + p_buffer[i] = AudioFrame(0, 0); + } + active = false; + todo = 0; + } + } + } +} + +float AudioStreamPlaybackMP3::get_stream_sampling_rate() { + return mp3_stream->sample_rate; +} + +void AudioStreamPlaybackMP3::start(float p_from_pos) { + active = true; + seek(p_from_pos); + loops = 0; + _begin_resample(); +} + +void AudioStreamPlaybackMP3::stop() { + active = false; +} + +bool AudioStreamPlaybackMP3::is_playing() const { + return active; +} + +int AudioStreamPlaybackMP3::get_loop_count() const { + return loops; +} + +float AudioStreamPlaybackMP3::get_playback_position() const { + return float(frames_mixed) / mp3_stream->sample_rate; +} + +void AudioStreamPlaybackMP3::seek(float p_time) { + if (!active) + return; + + if (p_time >= mp3_stream->get_length()) { + p_time = 0; + } + + frames_mixed = uint32_t(mp3_stream->sample_rate * p_time); + mp3dec_ex_seek(mp3d, frames_mixed * mp3_stream->channels); +} + +AudioStreamPlaybackMP3::~AudioStreamPlaybackMP3() { + if (mp3d) { + mp3dec_ex_close(mp3d); + memfree(mp3d); + } +} + +Ref<AudioStreamPlayback> AudioStreamMP3::instance_playback() { + Ref<AudioStreamPlaybackMP3> mp3s; + + ERR_FAIL_COND_V(data == nullptr, mp3s); + + mp3s.instance(); + mp3s->mp3_stream = Ref<AudioStreamMP3>(this); + mp3s->mp3d = (mp3dec_ex_t *)memalloc(sizeof(mp3dec_ex_t)); + + int errorcode = mp3dec_ex_open_buf(mp3s->mp3d, (const uint8_t *)data, data_len, MP3D_SEEK_TO_SAMPLE); + + mp3s->frames_mixed = 0; + mp3s->active = false; + mp3s->loops = 0; + + if (errorcode) { + ERR_FAIL_COND_V(errorcode, Ref<AudioStreamPlaybackMP3>()); + } + + return mp3s; +} + +String AudioStreamMP3::get_stream_name() const { + return ""; //return stream_name; +} + +void AudioStreamMP3::clear_data() { + if (data) { + memfree(data); + data = nullptr; + data_len = 0; + } +} + +void AudioStreamMP3::set_data(const Vector<uint8_t> &p_data) { + int src_data_len = p_data.size(); + const uint8_t *src_datar = p_data.ptr(); + + mp3dec_ex_t mp3d; + mp3dec_ex_open_buf(&mp3d, src_datar, src_data_len, MP3D_SEEK_TO_SAMPLE); + + channels = mp3d.info.channels; + sample_rate = mp3d.info.hz; + length = float(mp3d.samples) / (sample_rate * float(channels)); + + mp3dec_ex_close(&mp3d); + + clear_data(); + + data = memalloc(src_data_len); + copymem(data, src_datar, src_data_len); + data_len = src_data_len; +} + +Vector<uint8_t> AudioStreamMP3::get_data() const { + Vector<uint8_t> vdata; + + if (data_len && data) { + vdata.resize(data_len); + { + uint8_t *w = vdata.ptrw(); + copymem(w, data, data_len); + } + } + + return vdata; +} + +void AudioStreamMP3::set_loop(bool p_enable) { + loop = p_enable; +} + +bool AudioStreamMP3::has_loop() const { + return loop; +} + +void AudioStreamMP3::set_loop_offset(float p_seconds) { + loop_offset = p_seconds; +} + +float AudioStreamMP3::get_loop_offset() const { + return loop_offset; +} + +float AudioStreamMP3::get_length() const { + return length; +} + +void AudioStreamMP3::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamMP3::set_data); + ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamMP3::get_data); + + ClassDB::bind_method(D_METHOD("set_loop", "enable"), &AudioStreamMP3::set_loop); + ClassDB::bind_method(D_METHOD("has_loop"), &AudioStreamMP3::has_loop); + + ClassDB::bind_method(D_METHOD("set_loop_offset", "seconds"), &AudioStreamMP3::set_loop_offset); + ClassDB::bind_method(D_METHOD("get_loop_offset"), &AudioStreamMP3::get_loop_offset); + + ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_loop", "has_loop"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_loop_offset", "get_loop_offset"); +} + +AudioStreamMP3::AudioStreamMP3() { +} + +AudioStreamMP3::~AudioStreamMP3() { + clear_data(); +} diff --git a/modules/minimp3/audio_stream_mp3.h b/modules/minimp3/audio_stream_mp3.h new file mode 100644 index 0000000000..8d67190ac5 --- /dev/null +++ b/modules/minimp3/audio_stream_mp3.h @@ -0,0 +1,110 @@ +/*************************************************************************/ +/* audio_stream_mp3.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef AUDIO_STREAM_MP3_H +#define AUDIO_STREAM_MP3_H + +#include "core/io/resource_loader.h" +#include "servers/audio/audio_stream.h" + +#include "minimp3_ex.h" + +class AudioStreamMP3; + +class AudioStreamPlaybackMP3 : public AudioStreamPlaybackResampled { + GDCLASS(AudioStreamPlaybackMP3, AudioStreamPlaybackResampled); + + mp3dec_ex_t *mp3d = nullptr; + uint32_t frames_mixed = 0; + bool active = false; + int loops = 0; + + friend class AudioStreamMP3; + + Ref<AudioStreamMP3> mp3_stream; + +protected: + virtual void _mix_internal(AudioFrame *p_buffer, int p_frames) override; + virtual float get_stream_sampling_rate() override; + +public: + virtual void start(float p_from_pos = 0.0) override; + virtual void stop() override; + virtual bool is_playing() const override; + + virtual int get_loop_count() const override; //times it looped + + virtual float get_playback_position() const override; + virtual void seek(float p_time) override; + + AudioStreamPlaybackMP3() {} + ~AudioStreamPlaybackMP3(); +}; + +class AudioStreamMP3 : public AudioStream { + GDCLASS(AudioStreamMP3, AudioStream); + OBJ_SAVE_TYPE(AudioStream) //children are all saved as AudioStream, so they can be exchanged + RES_BASE_EXTENSION("mp3str"); + + friend class AudioStreamPlaybackMP3; + + void *data = nullptr; + uint32_t data_len = 0; + + float sample_rate = 1; + int channels = 1; + float length = 0; + bool loop = false; + float loop_offset = 0; + void clear_data(); + +protected: + static void _bind_methods(); + +public: + void set_loop(bool p_enable); + bool has_loop() const; + + void set_loop_offset(float p_seconds); + float get_loop_offset() const; + + virtual Ref<AudioStreamPlayback> instance_playback() override; + virtual String get_stream_name() const override; + + void set_data(const Vector<uint8_t> &p_data); + Vector<uint8_t> get_data() const; + + virtual float get_length() const override; + + AudioStreamMP3(); + virtual ~AudioStreamMP3(); +}; + +#endif // AUDIO_STREAM_MP3_H diff --git a/modules/minimp3/config.py b/modules/minimp3/config.py new file mode 100644 index 0000000000..bd35d099b9 --- /dev/null +++ b/modules/minimp3/config.py @@ -0,0 +1,16 @@ +def can_build(env, platform): + return True + + +def configure(env): + pass + + +def get_doc_classes(): + return [ + "AudioStreamMP3", + ] + + +def get_doc_path(): + return "doc_classes" diff --git a/modules/minimp3/doc_classes/AudioStreamMP3.xml b/modules/minimp3/doc_classes/AudioStreamMP3.xml new file mode 100644 index 0000000000..92e777ca0f --- /dev/null +++ b/modules/minimp3/doc_classes/AudioStreamMP3.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="AudioStreamMP3" inherits="AudioStream" version="4.0"> + <brief_description> + MP3 audio stream driver. + </brief_description> + <description> + MP3 audio stream driver. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="data" type="PackedByteArray" setter="set_data" getter="get_data" default="PackedByteArray( )"> + Contains the audio data in bytes. + </member> + <member name="loop" type="bool" setter="set_loop" getter="has_loop" default="false"> + If [code]true[/code], the stream will automatically loop when it reaches the end. + </member> + <member name="loop_offset" type="float" setter="set_loop_offset" getter="get_loop_offset" default="0.0"> + Time in seconds at which the stream starts after being looped. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/minimp3/register_types.cpp b/modules/minimp3/register_types.cpp new file mode 100644 index 0000000000..2c648b8efe --- /dev/null +++ b/modules/minimp3/register_types.cpp @@ -0,0 +1,52 @@ +/*************************************************************************/ +/* register_types.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "register_types.h" + +#include "audio_stream_mp3.h" + +#ifdef TOOLS_ENABLED +#include "core/config/engine.h" +#include "resource_importer_mp3.h" +#endif + +void register_minimp3_types() { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + Ref<ResourceImporterMP3> mp3_import; + mp3_import.instance(); + ResourceFormatImporter::get_singleton()->add_importer(mp3_import); + } +#endif + ClassDB::register_class<AudioStreamMP3>(); +} + +void unregister_minimp3_types() { +} diff --git a/modules/minimp3/register_types.h b/modules/minimp3/register_types.h new file mode 100644 index 0000000000..0d841e4987 --- /dev/null +++ b/modules/minimp3/register_types.h @@ -0,0 +1,37 @@ +/*************************************************************************/ +/* register_types.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef MINIMP3_REGISTER_TYPES_H +#define MINIMP3_REGISTER_TYPES_H + +void register_minimp3_types(); +void unregister_minimp3_types(); + +#endif // MINIMP3_REGISTER_TYPES_H diff --git a/modules/minimp3/resource_importer_mp3.cpp b/modules/minimp3/resource_importer_mp3.cpp new file mode 100644 index 0000000000..82e536a755 --- /dev/null +++ b/modules/minimp3/resource_importer_mp3.cpp @@ -0,0 +1,104 @@ +/*************************************************************************/ +/* resource_importer_mp3.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "resource_importer_mp3.h" + +#include "core/io/resource_saver.h" +#include "core/os/file_access.h" +#include "scene/resources/texture.h" + +String ResourceImporterMP3::get_importer_name() const { + return "mp3"; +} + +String ResourceImporterMP3::get_visible_name() const { + return "MP3"; +} + +void ResourceImporterMP3::get_recognized_extensions(List<String> *p_extensions) const { + p_extensions->push_back("mp3"); +} + +String ResourceImporterMP3::get_save_extension() const { + return "mp3str"; +} + +String ResourceImporterMP3::get_resource_type() const { + return "AudioStreamMP3"; +} + +bool ResourceImporterMP3::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { + return true; +} + +int ResourceImporterMP3::get_preset_count() const { + return 0; +} + +String ResourceImporterMP3::get_preset_name(int p_idx) const { + return String(); +} + +void ResourceImporterMP3::get_import_options(List<ImportOption> *r_options, int p_preset) const { + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "loop_offset"), 0)); +} + +Error ResourceImporterMP3::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { + bool loop = p_options["loop"]; + float loop_offset = p_options["loop_offset"]; + + FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ); + + ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); + + size_t len = f->get_len(); + + Vector<uint8_t> data; + data.resize(len); + uint8_t *w = data.ptrw(); + + f->get_buffer(w, len); + + memdelete(f); + + Ref<AudioStreamMP3> mp3_stream; + mp3_stream.instance(); + + mp3_stream->set_data(data); + ERR_FAIL_COND_V(!mp3_stream->get_data().size(), ERR_FILE_CORRUPT); + mp3_stream->set_loop(loop); + mp3_stream->set_loop_offset(loop_offset); + + return ResourceSaver::save(p_save_path + ".mp3str", mp3_stream); +} + +ResourceImporterMP3::ResourceImporterMP3() { +} diff --git a/modules/minimp3/resource_importer_mp3.h b/modules/minimp3/resource_importer_mp3.h new file mode 100644 index 0000000000..c1e8315e21 --- /dev/null +++ b/modules/minimp3/resource_importer_mp3.h @@ -0,0 +1,58 @@ +/*************************************************************************/ +/* resource_importer_mp3.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef RESOURCE_IMPORTER_MP3_H +#define RESOURCE_IMPORTER_MP3_H + +#include "audio_stream_mp3.h" +#include "core/io/resource_importer.h" + +class ResourceImporterMP3 : public ResourceImporter { + GDCLASS(ResourceImporterMP3, ResourceImporter); + +public: + virtual String get_importer_name() const override; + virtual String get_visible_name() const override; + virtual void get_recognized_extensions(List<String> *p_extensions) const override; + virtual String get_save_extension() const override; + virtual String get_resource_type() const override; + + virtual int get_preset_count() const override; + virtual String get_preset_name(int p_idx) const override; + + virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override; + virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override; + + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + + ResourceImporterMP3(); +}; + +#endif // RESOURCE_IMPORTER_MP3_H |