Merge pull request #58005 from akien-mga/3.x-cherrypicks

This commit is contained in:
Rémi Verschelde 2022-02-15 14:53:49 +01:00 committed by GitHub
commit 6235bd2a78
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 117 additions and 70 deletions

View file

@ -99,7 +99,8 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r
return OK;
}
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_objects) {
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_objects, int p_depth) {
ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, ERR_OUT_OF_MEMORY, "Variant is too deep. Bailing.");
const uint8_t *buf = p_buffer;
int len = p_len;
@ -430,7 +431,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
Variant value;
int used;
err = decode_variant(value, buf, len, &used, p_allow_objects);
err = decode_variant(value, buf, len, &used, p_allow_objects, p_depth + 1);
if (err) {
return err;
}
@ -473,7 +474,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
Variant key, value;
int used;
Error err = decode_variant(key, buf, len, &used, p_allow_objects);
Error err = decode_variant(key, buf, len, &used, p_allow_objects, p_depth + 1);
ERR_FAIL_COND_V_MSG(err != OK, err, "Error when trying to decode Variant.");
buf += used;
@ -482,7 +483,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
(*r_len) += used;
}
err = decode_variant(value, buf, len, &used, p_allow_objects);
err = decode_variant(value, buf, len, &used, p_allow_objects, p_depth + 1);
ERR_FAIL_COND_V_MSG(err != OK, err, "Error when trying to decode Variant.");
buf += used;
@ -515,7 +516,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
for (int i = 0; i < count; i++) {
int used = 0;
Variant v;
Error err = decode_variant(v, buf, len, &used, p_allow_objects);
Error err = decode_variant(v, buf, len, &used, p_allow_objects, p_depth + 1);
ERR_FAIL_COND_V_MSG(err != OK, err, "Error when trying to decode Variant.");
buf += used;
len -= used;

View file

@ -180,7 +180,7 @@ public:
EncodedObjectAsID();
};
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = nullptr, bool p_allow_objects = false);
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = nullptr, bool p_allow_objects = false, int p_depth = 0);
Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects = false, int p_depth = 0);
#endif

View file

@ -531,7 +531,11 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
bool ProjectSettings::has_setting(String p_var) const {
_THREAD_SAFE_METHOD_
return props.has(p_var);
StringName name = p_var;
if (!disable_feature_overrides && feature_overrides.has(name)) {
name = feature_overrides[name];
}
return props.has(name);
}
void ProjectSettings::set_registering_order(bool p_enable) {

View file

@ -221,8 +221,8 @@
<method name="hash">
<return type="int" />
<description>
Returns a hashed integer value representing the array and its contents.
[b]Note:[/b] Arrays with equal contents can still produce different hashes. Only the exact same arrays will produce the same hashed integer value.
Returns a hashed 32-bit integer value representing the array and its contents.
[b]Note:[/b] [Array]s with equal content will always produce identical hash values. However, the reverse is not true. Returning identical hash values does [i]not[/i] imply the arrays are equal, because different arrays can have identical hash values due to hash collisions.
</description>
</method>
<method name="insert">

View file

@ -32,7 +32,7 @@
<method name="capture_get_device">
<return type="String" />
<description>
Name of the current device for audio input (see [method capture_get_device_list]).
Name of the current device for audio input (see [method capture_get_device_list]). The value [code]"Default"[/code] means that the system-wide default audio input is currently used.
</description>
</method>
<method name="capture_get_device_list">
@ -45,7 +45,7 @@
<return type="void" />
<argument index="0" name="name" type="String" />
<description>
Sets which audio input device is used for audio capture.
Sets which audio input device is used for audio capture. On systems with multiple audio inputs (such as analog and USB), this can be used to select the audio input device. Setting the value [code]"Default"[/code] will record audio from the system-wide default audio input. If an invalid device name is set, the value will be reverted back to [code]"Default"[/code].
</description>
</method>
<method name="generate_bus_layout" qualifiers="const">
@ -309,7 +309,7 @@
Number of available audio buses.
</member>
<member name="device" type="String" setter="set_device" getter="get_device" default="&quot;Default&quot;">
Name of the current device for audio output (see [method get_device_list]).
Name of the current device for audio output (see [method get_device_list]). On systems with multiple audio outputs (such as analog, USB and HDMI audio), this can be used to select the audio output device. The value [code]"Default"[/code] will play audio on the system-wide default audio output. If an invalid device name is set, the value will be reverted back to [code]"Default"[/code].
</member>
<member name="global_rate_scale" type="float" setter="set_global_rate_scale" getter="get_global_rate_scale" default="1.0">
Scales the rate at which audio is played (i.e. setting it to [code]0.5[/code] will make the audio be played twice as fast).

View file

@ -147,7 +147,7 @@
<method name="hash">
<return type="int" />
<description>
Returns a hashed integer value representing the dictionary contents. This can be used to compare dictionaries by value:
Returns a hashed 32-bit integer value representing the dictionary contents. This can be used to compare dictionaries by value:
[codeblock]
var dict1 = {0: 10}
var dict2 = {0: 10}
@ -155,6 +155,7 @@
print(dict1.hash() == dict2.hash())
[/codeblock]
[b]Note:[/b] Dictionaries with the same keys/values but in a different order will have a different hash.
[b]Note:[/b] Dictionaries with equal content will always produce identical hash values. However, the reverse is not true. Returning identical hash values does [i]not[/i] imply the dictionaries are equal, because different dictionaries can have identical hash values due to hash collisions.
</description>
</method>
<method name="keys">

View file

@ -351,7 +351,8 @@
<method name="hash">
<return type="int" />
<description>
Hashes the string and returns a 32-bit integer.
Returns the 32-bit hash value representing the string's contents.
[b]Note:[/b] [String]s with equal content will always produce identical hash values. However, the reverse is not true. Returning identical hash values does [i]not[/i] imply the strings are equal, because different strings can have identical hash values due to hash collisions.
</description>
</method>
<method name="hex_to_int">

View file

@ -273,6 +273,10 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
return false;
}
if (!_get_node()->is_visible_in_tree()) {
return false;
}
Ref<InputEventMouseButton> mb = p_event;
if (!_has_resource()) {
@ -506,6 +510,10 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
return;
}
if (!_get_node()->is_visible_in_tree()) {
return;
}
Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
// All polygon points are sharp, so use the sharp handle icon
const Ref<Texture> handle = get_icon("EditorPathSharpHandle", "EditorIcons");

View file

@ -326,6 +326,10 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e
return false;
}
if (!node->is_visible_in_tree()) {
return false;
}
if (shape_type == -1) {
return false;
}
@ -448,6 +452,10 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla
return;
}
if (!node->is_visible_in_tree()) {
return;
}
_get_current_shape_type();
if (shape_type == -1) {

View file

@ -271,7 +271,7 @@
<div id="tab-loader">
<div style="color: #e0e0e0;" id="persistence">
<br />
<img src="logo.svg" alt="Godot Engine logo" width="1024" height="414" style="width: auto; height: auto; max-width: 85%; max-height: 250px" />
<img src="logo.svg" alt="Godot Engine logo" width="1024" height="414" style="width: auto; height: auto; max-width: min(85%, 50vh); max-height: 250px" />
<br />
@GODOT_VERSION@
<br />

View file

@ -5,7 +5,6 @@
"lang": "en",
"start_url": "./godot.tools.html",
"display": "standalone",
"orientation": "landscape",
"theme_color": "#202531",
"icons": [
{

View file

@ -74,7 +74,7 @@
*
*****************************************************************************/
void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long fftFrameSize, long osamp, float sampleRate, float *indata, float *outdata,int stride) {
void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int64_t fftFrameSize, int64_t osamp, float sampleRate, float *indata, float *outdata,int stride) {
/*
@ -85,19 +85,32 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
*/
double magn, phase, tmp, window, real, imag;
double freqPerBin, expct;
long i,k, qpd, index, inFifoLatency, stepSize, fftFrameSize2;
double freqPerBin, expct, reciprocalFftFrameSize;
int64_t i,k, qpd, index, inFifoLatency, stepSize, fftFrameSize2;
/* set up some handy variables */
fftFrameSize2 = fftFrameSize/2;
reciprocalFftFrameSize = 1./fftFrameSize;
stepSize = fftFrameSize/osamp;
freqPerBin = sampleRate/(double)fftFrameSize;
expct = 2.*Math_PI*(double)stepSize/(double)fftFrameSize;
freqPerBin = reciprocalFftFrameSize * sampleRate;
expct = Math_TAU * reciprocalFftFrameSize * stepSize;
inFifoLatency = fftFrameSize-stepSize;
if (gRover == 0) { gRover = inFifoLatency;
}
if (gRover == 0) {
gRover = inFifoLatency;
}
/* initialize our static arrays */
// If pitchShift changes clear arrays to prevent some artifacts and quality loss.
if (lastPitchShift != pitchShift) {
lastPitchShift = pitchShift;
memset(gInFIFO, 0, MAX_FRAME_LENGTH * sizeof(float));
memset(gOutFIFO, 0, MAX_FRAME_LENGTH * sizeof(float));
memset(gFFTworksp, 0, 2 * MAX_FRAME_LENGTH * sizeof(double));
memset(gLastPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(double));
memset(gSumPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(double));
memset(gOutputAccum, 0, 2 * MAX_FRAME_LENGTH * sizeof(double));
memset(gAnaFreq, 0, MAX_FRAME_LENGTH * sizeof(double));
memset(gAnaMagn, 0, MAX_FRAME_LENGTH * sizeof(double));
}
/* main processing loop */
for (i = 0; i < numSampsToProcess; i++){
@ -113,7 +126,7 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
/* do windowing and re,im interleave */
for (k = 0; k < fftFrameSize;k++) {
window = -.5*cos(2.*Math_PI*(double)k/(double)fftFrameSize)+.5;
window = -.5*cos(Math_TAU * reciprocalFftFrameSize * k)+.5;
gFFTworksp[2*k] = gInFIFO[k] * window;
gFFTworksp[2*k+1] = 0.;
}
@ -143,13 +156,15 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
/* map delta phase into +/- Pi interval */
qpd = tmp/Math_PI;
if (qpd >= 0) { qpd += qpd&1;
} else { qpd -= qpd&1;
}
if (qpd >= 0) {
qpd += qpd&1;
} else {
qpd -= qpd&1;
}
tmp -= Math_PI*(double)qpd;
/* get deviation from bin frequency from the +/- Pi interval */
tmp = osamp*tmp/(2.*Math_PI);
tmp = osamp*tmp/Math_TAU;
/* compute the k-th partials' true frequency */
tmp = (double)k*freqPerBin + tmp*freqPerBin;
@ -162,8 +177,8 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
/* ***************** PROCESSING ******************* */
/* this does the actual pitch shifting */
memset(gSynMagn, 0, fftFrameSize*sizeof(float));
memset(gSynFreq, 0, fftFrameSize*sizeof(float));
memset(gSynMagn, 0, fftFrameSize*sizeof(double));
memset(gSynFreq, 0, fftFrameSize*sizeof(double));
for (k = 0; k <= fftFrameSize2; k++) {
index = k*pitchShift;
if (index <= fftFrameSize2) {
@ -187,7 +202,7 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
tmp /= freqPerBin;
/* take osamp into account */
tmp = 2.*Math_PI*tmp/osamp;
tmp = Math_TAU*tmp/osamp;
/* add the overlap phase advance back in */
tmp += (double)k*expct;
@ -202,35 +217,35 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
}
/* zero negative frequencies */
for (k = fftFrameSize+2; k < 2*fftFrameSize; k++) { gFFTworksp[k] = 0.;
}
for (k = fftFrameSize+2; k < 2*MAX_FRAME_LENGTH; k++) {
gFFTworksp[k] = 0.;
}
/* do inverse transform */
smbFft(gFFTworksp, fftFrameSize, 1);
/* do windowing and add to output accumulator */
for(k=0; k < fftFrameSize; k++) {
window = -.5*cos(2.*Math_PI*(double)k/(double)fftFrameSize)+.5;
window = -.5*cos(Math_TAU * reciprocalFftFrameSize * k)+.5;
gOutputAccum[k] += 2.*window*gFFTworksp[2*k]/(fftFrameSize2*osamp);
}
for (k = 0; k < stepSize; k++) { gOutFIFO[k] = gOutputAccum[k];
}
for (k = 0; k < stepSize; k++) {
gOutFIFO[k] = gOutputAccum[k];
}
/* shift accumulator */
memmove(gOutputAccum, gOutputAccum+stepSize, fftFrameSize*sizeof(float));
memmove(gOutputAccum, gOutputAccum+stepSize, fftFrameSize*sizeof(double));
/* move input FIFO */
for (k = 0; k < inFifoLatency; k++) { gInFIFO[k] = gInFIFO[k+stepSize];
}
for (k = 0; k < inFifoLatency; k++) {
gInFIFO[k] = gInFIFO[k+stepSize];
}
}
}
}
void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
void SMBPitchShift::smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t sign)
/*
FFT routine, (C)1996 S.M.Bernsee. Sign = -1 is FFT, 1 is iFFT (inverse)
Fills fftBuffer[0...2*fftFrameSize-1] with the Fourier transform of the
@ -243,14 +258,16 @@ void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
of the frequencies of interest is in fftBuffer[0...fftFrameSize].
*/
{
float wr, wi, arg, *p1, *p2, temp;
float tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i;
long i, bitm, j, le, le2, k;
double wr, wi, arg, *p1, *p2, temp;
double tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i;
int64_t i, bitm, j, le, le2, k, logN;
logN = (int64_t)(log(fftFrameSize) / log(2.) + .5);
for (i = 2; i < 2*fftFrameSize-2; i += 2) {
for (bitm = 2, j = 0; bitm < 2*fftFrameSize; bitm <<= 1) {
if (i & bitm) { j++;
}
if (i & bitm) {
j++;
}
j <<= 1;
}
if (i < j) {
@ -260,7 +277,8 @@ void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
*p1 = *p2; *p2 = temp;
}
}
for (k = 0, le = 2; k < (long)(log((double)fftFrameSize)/log(2.)+.5); k++) {
for (k = 0, le = 2; k < logN; k++) {
le <<= 1;
le2 = le>>1;
ur = 1.0;
@ -292,6 +310,14 @@ void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
void AudioEffectPitchShiftInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
float sample_rate = AudioServer::get_singleton()->get_mix_rate();
// For pitch_scale 1.0 it's cheaper to just pass samples without processing them.
if (Math::is_equal_approx(base->pitch_scale, 1.0f)) {
for (int i = 0; i < p_frame_count; i++) {
p_dst_frames[i] = p_src_frames[i];
}
return;
}
float *in_l = (float *)p_src_frames;
float *in_r = in_l + 1;

View file

@ -40,31 +40,33 @@ class SMBPitchShift {
float gInFIFO[MAX_FRAME_LENGTH];
float gOutFIFO[MAX_FRAME_LENGTH];
float gFFTworksp[2 * MAX_FRAME_LENGTH];
float gLastPhase[MAX_FRAME_LENGTH / 2 + 1];
float gSumPhase[MAX_FRAME_LENGTH / 2 + 1];
float gOutputAccum[2 * MAX_FRAME_LENGTH];
float gAnaFreq[MAX_FRAME_LENGTH];
float gAnaMagn[MAX_FRAME_LENGTH];
float gSynFreq[MAX_FRAME_LENGTH];
float gSynMagn[MAX_FRAME_LENGTH];
long gRover;
double gFFTworksp[2 * MAX_FRAME_LENGTH];
double gLastPhase[MAX_FRAME_LENGTH / 2 + 1];
double gSumPhase[MAX_FRAME_LENGTH / 2 + 1];
double gOutputAccum[2 * MAX_FRAME_LENGTH];
double gAnaFreq[MAX_FRAME_LENGTH];
double gAnaMagn[MAX_FRAME_LENGTH];
double gSynFreq[MAX_FRAME_LENGTH];
double gSynMagn[MAX_FRAME_LENGTH];
int64_t gRover;
float lastPitchShift;
void smbFft(float *fftBuffer, long fftFrameSize, long sign);
void smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t sign);
public:
void PitchShift(float pitchShift, long numSampsToProcess, long fftFrameSize, long osamp, float sampleRate, float *indata, float *outdata, int stride);
void PitchShift(float pitchShift, int64_t numSampsToProcess, int64_t fftFrameSize, int64_t osamp, float sampleRate, float *indata, float *outdata, int stride);
SMBPitchShift() {
gRover = 0;
memset(gInFIFO, 0, MAX_FRAME_LENGTH * sizeof(float));
memset(gOutFIFO, 0, MAX_FRAME_LENGTH * sizeof(float));
memset(gFFTworksp, 0, 2 * MAX_FRAME_LENGTH * sizeof(float));
memset(gLastPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(float));
memset(gSumPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(float));
memset(gOutputAccum, 0, 2 * MAX_FRAME_LENGTH * sizeof(float));
memset(gAnaFreq, 0, MAX_FRAME_LENGTH * sizeof(float));
memset(gAnaMagn, 0, MAX_FRAME_LENGTH * sizeof(float));
memset(gFFTworksp, 0, 2 * MAX_FRAME_LENGTH * sizeof(double));
memset(gLastPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(double));
memset(gSumPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(double));
memset(gOutputAccum, 0, 2 * MAX_FRAME_LENGTH * sizeof(double));
memset(gAnaFreq, 0, MAX_FRAME_LENGTH * sizeof(double));
memset(gAnaMagn, 0, MAX_FRAME_LENGTH * sizeof(double));
lastPitchShift = 1.0;
}
};
@ -101,9 +103,6 @@ public:
float pitch_scale;
int oversampling;
FFT_Size fft_size;
float wet;
float dry;
bool filter;
protected:
static void _bind_methods();