feat: updated engine version to 4.4-rc1
This commit is contained in:
parent
ee00efde1f
commit
21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
from misc.utility.scons_hints import *
|
||||
|
||||
Import("env")
|
||||
Import("env_modules")
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@
|
|||
|
||||
#include "audio_stream_mp3.h"
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
|
||||
int AudioStreamPlaybackMP3::_mix_internal(AudioFrame *p_buffer, int p_frames) {
|
||||
if (!active) {
|
||||
return 0;
|
||||
|
|
@ -57,7 +55,7 @@ int AudioStreamPlaybackMP3::_mix_internal(AudioFrame *p_buffer, int p_frames) {
|
|||
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);
|
||||
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]);
|
||||
|
|
@ -70,7 +68,7 @@ int AudioStreamPlaybackMP3::_mix_internal(AudioFrame *p_buffer, int p_frames) {
|
|||
|
||||
if (beat_loop && (int)frames_mixed >= beat_length_frames) {
|
||||
for (int i = 0; i < FADE_SIZE; i++) {
|
||||
samples_mixed = mp3dec_ex_read_frame(mp3d, &buf_frame, &frame_info, mp3_stream->channels);
|
||||
samples_mixed = mp3dec_ex_read_frame(&mp3d, &buf_frame, &frame_info, mp3_stream->channels);
|
||||
loop_fade[i] = AudioFrame(buf_frame[0], buf_frame[samples_mixed - 1]);
|
||||
if (!samples_mixed) {
|
||||
break;
|
||||
|
|
@ -138,7 +136,7 @@ void AudioStreamPlaybackMP3::seek(double p_time) {
|
|||
}
|
||||
|
||||
frames_mixed = uint32_t(mp3_stream->sample_rate * p_time);
|
||||
mp3dec_ex_seek(mp3d, (uint64_t)frames_mixed * mp3_stream->channels);
|
||||
mp3dec_ex_seek(&mp3d, (uint64_t)frames_mixed * mp3_stream->channels);
|
||||
}
|
||||
|
||||
void AudioStreamPlaybackMP3::tag_used_streams() {
|
||||
|
|
@ -159,6 +157,9 @@ Ref<AudioSamplePlayback> AudioStreamPlaybackMP3::get_sample_playback() const {
|
|||
|
||||
void AudioStreamPlaybackMP3::set_sample_playback(const Ref<AudioSamplePlayback> &p_playback) {
|
||||
sample_playback = p_playback;
|
||||
if (sample_playback.is_valid()) {
|
||||
sample_playback->stream_playback = Ref<AudioStreamPlayback>(this);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioStreamPlaybackMP3::set_parameter(const StringName &p_name, const Variant &p_value) {
|
||||
|
|
@ -181,10 +182,7 @@ Variant AudioStreamPlaybackMP3::get_parameter(const StringName &p_name) const {
|
|||
}
|
||||
|
||||
AudioStreamPlaybackMP3::~AudioStreamPlaybackMP3() {
|
||||
if (mp3d) {
|
||||
mp3dec_ex_close(mp3d);
|
||||
memfree(mp3d);
|
||||
}
|
||||
mp3dec_ex_close(&mp3d);
|
||||
}
|
||||
|
||||
Ref<AudioStreamPlayback> AudioStreamMP3::instantiate_playback() {
|
||||
|
|
@ -197,9 +195,8 @@ Ref<AudioStreamPlayback> AudioStreamMP3::instantiate_playback() {
|
|||
|
||||
mp3s.instantiate();
|
||||
mp3s->mp3_stream = Ref<AudioStreamMP3>(this);
|
||||
mp3s->mp3d = (mp3dec_ex_t *)memalloc(sizeof(mp3dec_ex_t));
|
||||
|
||||
int errorcode = mp3dec_ex_open_buf(mp3s->mp3d, data.ptr(), data_len, MP3D_SEEK_TO_SAMPLE);
|
||||
int errorcode = mp3dec_ex_open_buf(&mp3s->mp3d, data.ptr(), data_len, MP3D_SEEK_TO_SAMPLE);
|
||||
|
||||
mp3s->frames_mixed = 0;
|
||||
mp3s->active = false;
|
||||
|
|
@ -222,22 +219,22 @@ void AudioStreamMP3::clear_data() {
|
|||
|
||||
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;
|
||||
int err = mp3dec_ex_open_buf(&mp3d, src_datar, src_data_len, MP3D_SEEK_TO_SAMPLE);
|
||||
ERR_FAIL_COND_MSG(err || mp3d.info.hz == 0, "Failed to decode mp3 file. Make sure it is a valid mp3 audio file.");
|
||||
mp3dec_ex_t *mp3d = memnew(mp3dec_ex_t);
|
||||
int err = mp3dec_ex_open_buf(mp3d, p_data.ptr(), src_data_len, MP3D_SEEK_TO_SAMPLE);
|
||||
if (err || mp3d->info.hz == 0) {
|
||||
memdelete(mp3d);
|
||||
ERR_FAIL_MSG("Failed to decode mp3 file. Make sure it is a valid mp3 audio file.");
|
||||
}
|
||||
|
||||
channels = mp3d.info.channels;
|
||||
sample_rate = mp3d.info.hz;
|
||||
length = float(mp3d.samples) / (sample_rate * float(channels));
|
||||
channels = mp3d->info.channels;
|
||||
sample_rate = mp3d->info.hz;
|
||||
length = float(mp3d->samples) / (sample_rate * float(channels));
|
||||
|
||||
mp3dec_ex_close(&mp3d);
|
||||
mp3dec_ex_close(mp3d);
|
||||
memdelete(mp3d);
|
||||
|
||||
clear_data();
|
||||
|
||||
data.resize(src_data_len);
|
||||
memcpy(data.ptrw(), src_datar, src_data_len);
|
||||
data = p_data;
|
||||
data_len = src_data_len;
|
||||
}
|
||||
|
||||
|
|
@ -315,7 +312,24 @@ Ref<AudioSample> AudioStreamMP3::generate_sample() const {
|
|||
return sample;
|
||||
}
|
||||
|
||||
Ref<AudioStreamMP3> AudioStreamMP3::load_from_buffer(const Vector<uint8_t> &p_stream_data) {
|
||||
Ref<AudioStreamMP3> mp3_stream;
|
||||
mp3_stream.instantiate();
|
||||
mp3_stream->set_data(p_stream_data);
|
||||
ERR_FAIL_COND_V_MSG(mp3_stream->get_data().is_empty(), Ref<AudioStreamMP3>(), "MP3 decoding failed. Check that your data is a valid MP3 audio stream.");
|
||||
return mp3_stream;
|
||||
}
|
||||
|
||||
Ref<AudioStreamMP3> AudioStreamMP3::load_from_file(const String &p_path) {
|
||||
const Vector<uint8_t> stream_data = FileAccess::get_file_as_bytes(p_path);
|
||||
ERR_FAIL_COND_V_MSG(stream_data.is_empty(), Ref<AudioStreamMP3>(), vformat("Cannot open file '%s'.", p_path));
|
||||
return load_from_buffer(stream_data);
|
||||
}
|
||||
|
||||
void AudioStreamMP3::_bind_methods() {
|
||||
ClassDB::bind_static_method("AudioStreamMP3", D_METHOD("load_from_buffer", "stream_data"), &AudioStreamMP3::load_from_buffer);
|
||||
ClassDB::bind_static_method("AudioStreamMP3", D_METHOD("load_from_file", "path"), &AudioStreamMP3::load_from_file);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamMP3::set_data);
|
||||
ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamMP3::get_data);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#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>
|
||||
|
|
@ -49,7 +48,7 @@ class AudioStreamPlaybackMP3 : public AudioStreamPlaybackResampled {
|
|||
|
||||
bool looping_override = false;
|
||||
bool looping = false;
|
||||
mp3dec_ex_t *mp3d = nullptr;
|
||||
mp3dec_ex_t mp3d = {};
|
||||
uint32_t frames_mixed = 0;
|
||||
bool active = false;
|
||||
int loops = 0;
|
||||
|
|
@ -96,7 +95,7 @@ class AudioStreamMP3 : public AudioStream {
|
|||
|
||||
friend class AudioStreamPlaybackMP3;
|
||||
|
||||
PackedByteArray data;
|
||||
LocalVector<uint8_t> data;
|
||||
uint32_t data_len = 0;
|
||||
|
||||
float sample_rate = 1.0;
|
||||
|
|
@ -114,6 +113,9 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
static Ref<AudioStreamMP3> load_from_buffer(const Vector<uint8_t> &p_stream_data);
|
||||
static Ref<AudioStreamMP3> load_from_file(const String &p_path);
|
||||
|
||||
void set_loop(bool p_enable);
|
||||
virtual bool has_loop() const override;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,26 @@
|
|||
</brief_description>
|
||||
<description>
|
||||
MP3 audio stream driver. See [member data] if you want to load an MP3 file at run-time.
|
||||
[b]Note:[/b] This class can optionally support legacy MP1 and MP2 formats, provided that the engine is compiled with the [code]minimp3_extra_formats=yes[/code] SCons option. These extra formats are not enabled by default.
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="load_from_buffer" qualifiers="static">
|
||||
<return type="AudioStreamMP3" />
|
||||
<param index="0" name="stream_data" type="PackedByteArray" />
|
||||
<description>
|
||||
Creates a new [AudioStreamMP3] instance from the given buffer. The buffer must contain MP3 data.
|
||||
</description>
|
||||
</method>
|
||||
<method name="load_from_file" qualifiers="static">
|
||||
<return type="AudioStreamMP3" />
|
||||
<param index="0" name="path" type="String" />
|
||||
<description>
|
||||
Creates a new [AudioStreamMP3] instance from the given file path. The file must be in MP3 format.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="bar_beats" type="int" setter="set_bar_beats" getter="get_bar_beats" default="4">
|
||||
</member>
|
||||
|
|
|
|||
|
|
@ -13,15 +13,15 @@
|
|||
</tutorials>
|
||||
<members>
|
||||
<member name="bar_beats" type="int" setter="" getter="" default="4">
|
||||
The number of bars within a single beat in the audio track. This is only relevant for music that wishes to make use of interactive music functionality (not implemented yet), not sound effects.
|
||||
The number of bars within a single beat in the audio track. This is only relevant for music that wishes to make use of interactive music functionality, not sound effects.
|
||||
A more convenient editor for [member bar_beats] is provided in the [b]Advanced Import Settings[/b] dialog, as it lets you preview your changes without having to reimport the audio.
|
||||
</member>
|
||||
<member name="beat_count" type="int" setter="" getter="" default="0">
|
||||
The beat count of the audio track. This is only relevant for music that wishes to make use of interactive music functionality (not implemented yet), not sound effects.
|
||||
The beat count of the audio track. This is only relevant for music that wishes to make use of interactive music functionality, not sound effects.
|
||||
A more convenient editor for [member beat_count] is provided in the [b]Advanced Import Settings[/b] dialog, as it lets you preview your changes without having to reimport the audio.
|
||||
</member>
|
||||
<member name="bpm" type="float" setter="" getter="" default="0">
|
||||
The Beats Per Minute of the audio track. This should match the BPM measure that was used to compose the track. This is only relevant for music that wishes to make use of interactive music functionality (not implemented yet), not sound effects.
|
||||
The beats per minute of the audio track. This should match the BPM measure that was used to compose the track. This is only relevant for music that wishes to make use of interactive music functionality, not sound effects.
|
||||
A more convenient editor for [member bpm] is provided in the [b]Advanced Import Settings[/b] dialog, as it lets you preview your changes without having to reimport the audio.
|
||||
</member>
|
||||
<member name="loop" type="bool" setter="" getter="" default="false">
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/io/resource_saver.h"
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
#include "editor/import/audio_stream_import_settings.h"
|
||||
|
|
@ -86,46 +85,27 @@ void ResourceImporterMP3::get_import_options(const String &p_path, List<ImportOp
|
|||
bool ResourceImporterMP3::has_advanced_options() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ResourceImporterMP3::show_advanced_options(const String &p_path) {
|
||||
Ref<AudioStreamMP3> mp3_stream = import_mp3(p_path);
|
||||
Ref<AudioStreamMP3> mp3_stream = AudioStreamMP3::load_from_file(p_path);
|
||||
if (mp3_stream.is_valid()) {
|
||||
AudioStreamImportSettingsDialog::get_singleton()->edit(p_path, "mp3", mp3_stream);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Ref<AudioStreamMP3> ResourceImporterMP3::import_mp3(const String &p_path) {
|
||||
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
|
||||
ERR_FAIL_COND_V(f.is_null(), Ref<AudioStreamMP3>());
|
||||
|
||||
uint64_t len = f->get_length();
|
||||
|
||||
Vector<uint8_t> data;
|
||||
data.resize(len);
|
||||
uint8_t *w = data.ptrw();
|
||||
|
||||
f->get_buffer(w, len);
|
||||
|
||||
Ref<AudioStreamMP3> mp3_stream;
|
||||
mp3_stream.instantiate();
|
||||
|
||||
mp3_stream->set_data(data);
|
||||
ERR_FAIL_COND_V(mp3_stream->get_data().is_empty(), Ref<AudioStreamMP3>());
|
||||
|
||||
return mp3_stream;
|
||||
}
|
||||
|
||||
Error ResourceImporterMP3::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
|
||||
Error ResourceImporterMP3::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<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"];
|
||||
double bpm = p_options["bpm"];
|
||||
float beat_count = p_options["beat_count"];
|
||||
float bar_beats = p_options["bar_beats"];
|
||||
|
||||
Ref<AudioStreamMP3> mp3_stream = import_mp3(p_source_file);
|
||||
Ref<AudioStreamMP3> mp3_stream = AudioStreamMP3::load_from_file(p_source_file);
|
||||
if (mp3_stream.is_null()) {
|
||||
return ERR_CANT_OPEN;
|
||||
}
|
||||
|
||||
mp3_stream->set_loop(loop);
|
||||
mp3_stream->set_loop_offset(loop_offset);
|
||||
mp3_stream->set_bpm(bpm);
|
||||
|
|
|
|||
|
|
@ -55,9 +55,10 @@ public:
|
|||
virtual bool has_advanced_options() const override;
|
||||
virtual void show_advanced_options(const String &p_path) override;
|
||||
#endif
|
||||
static Ref<AudioStreamMP3> import_mp3(const String &p_path);
|
||||
|
||||
virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
|
||||
virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
|
||||
|
||||
virtual bool can_import_threaded() const override { return true; }
|
||||
|
||||
ResourceImporterMP3();
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue