From 54eac2aba56941658fb18206219ad60b648ab6f2 Mon Sep 17 00:00:00 2001
From: Markus Sauermann <6299227+Sauermann@users.noreply.github.com>
Date: Mon, 21 Feb 2022 09:30:14 +0100
Subject: [PATCH 01/10] Update doc for match: empty argument doesn't match
anything
(cherry picked from commit 70ae6c21de9fd3f0e00a052b15f70c3667836898)
---
doc/classes/String.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index 1e2dfacd4aa..2d1b975729e 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -523,14 +523,14 @@
- Does a simple case-sensitive expression match, where [code]"*"[/code] matches zero or more arbitrary characters and [code]"?"[/code] matches any single character except a period ([code]"."[/code]).
+ Does a simple case-sensitive expression match, where [code]"*"[/code] matches zero or more arbitrary characters and [code]"?"[/code] matches any single character except a period ([code]"."[/code]). An empty string or empty expression always evaluates to [code]false[/code].
- Does a simple case-insensitive expression match, where [code]"*"[/code] matches zero or more arbitrary characters and [code]"?"[/code] matches any single character except a period ([code]"."[/code]).
+ Does a simple case-insensitive expression match, where [code]"*"[/code] matches zero or more arbitrary characters and [code]"?"[/code] matches any single character except a period ([code]"."[/code]). An empty string or empty expression always evaluates to [code]false[/code].
From c4041ca8c02846f9ab004fcfe812e74e26f2da43 Mon Sep 17 00:00:00 2001
From: Nova <3247833+novaplusplus@users.noreply.github.com>
Date: Tue, 22 Feb 2022 15:13:34 -0500
Subject: [PATCH 02/10] Added or improved documentation to a few more String
methods
(cherry picked from commit f159e7e5ab2a833412d458343a6eb2896a8abb56)
---
doc/classes/String.xml | 34 +++++++++++++++++++++++++++++++---
1 file changed, 31 insertions(+), 3 deletions(-)
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index 2d1b975729e..a7d59fd32c7 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -188,7 +188,10 @@
- Returns the bigrams (pairs of consecutive letters) of this string.
+ Returns an array containing the bigrams (pairs of consecutive letters) of this string.
+ [codeblock]
+ print("Bigrams".bigrams()) # Prints "[Bi, ig, gr, ra, am, ms]"
+ [/codeblock]
@@ -447,7 +450,14 @@
- Returns [code]true[/code] if this string contains a valid float.
+ Returns [code]true[/code] if this string contains a valid float. This is inclusive of integers, and also supports exponents:
+ [codeblock]
+ print("1.7".is_valid_float()) # Prints "true"
+ print("24".is_valid_float()) # Prints "true"
+ print("7e3".is_valid_float()) # Prints "true"
+ print("24".is_valid_float()) # Prints "true"
+ print("Hello".is_valid_float()) # Prints "false"
+ [/codeblock]
@@ -467,12 +477,24 @@
Returns [code]true[/code] if this string is a valid identifier. A valid identifier may contain only letters, digits and underscores ([code]_[/code]) and the first character may not be a digit.
+ [codeblock]
+ print("good_ident_1".is_valid_identifier()) # Prints "true"
+ print("1st_bad_ident".is_valid_identifier()) # Prints "false"
+ print("bad_ident_#2".is_valid_identifier()) # Prints "false"
+ [/codeblock]
Returns [code]true[/code] if this string contains a valid integer.
+ [codeblock]
+ print("7".is_valid_int()) # Prints "true"
+ print("14.6".is_valid_int()) # Prints "false"
+ print("L".is_valid_int()) # Prints "false"
+ print("+3".is_valid_int()) # Prints "true"
+ print("-12".is_valid_int()) # Prints "true"
+ [/codeblock]
@@ -707,7 +729,13 @@
- Returns the similarity index of the text compared to this string. 1 means totally similar and 0 means totally dissimilar.
+ Returns the similarity index ([url=https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient]Sorensen-Dice coefficient[/url]) this string compared to another. 1.0 means totally similar and 0.0 means totally dissimilar.
+ [codeblock]
+ print("ABC123".similarity("ABC123")) # Prints "1"
+ print("ABC123".similarity("XYZ456")) # Prints "0"
+ print("ABC123".similarity("123ABC")) # Prints "0.8"
+ print("ABC123".similarity("abc123")) # Prints "0.4"
+ [/codeblock]
From 8bbcc624fdd86bb6edeb51d16b238264d472647d Mon Sep 17 00:00:00 2001
From: janglee
Date: Tue, 7 Apr 2020 18:13:46 +0530
Subject: [PATCH 03/10] Fixed underlines and striketrough not respecting
visible character
(cherry picked from commit 9c2c2ab2b0485b83148f636318ccecd903e4af8a)
---
scene/gui/rich_text_label.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index c14b8eb48ff..d61b6ba9342 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -437,7 +437,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
was_separatable = separatable;
just_breaked_in_middle = false;
- w += cw;
fw += cw;
end++;
@@ -579,6 +578,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
if (visible) {
line_is_blank = false;
+ w += font->get_char_size(c[i], c[i + 1]).x;
}
if (c[i] == '\t') {
From a1155b86e41f80b683783222470ae84d20415750 Mon Sep 17 00:00:00 2001
From: janglee
Date: Mon, 13 Apr 2020 14:59:38 +0530
Subject: [PATCH 04/10] Fixed 0 width issue of rich text label Fixes #37746
(cherry picked from commit 5e64c146bc0bbc6896d4ae6dc54545c2c6413a90)
---
scene/gui/rich_text_label.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index d61b6ba9342..50a4b3135df 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -414,7 +414,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
cw = tab_size * font->get_char_size(' ').width;
}
- if (end > 0 && w + cw + begin > p_width) {
+ if (end > 0 && fw + cw + begin > p_width) {
break; //don't allow lines longer than assigned width
}
@@ -442,7 +442,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
end++;
}
CHECK_HEIGHT(fh);
- ENSURE_WIDTH(w);
+ ENSURE_WIDTH(fw);
line_ascent = MAX(line_ascent, ascent);
line_descent = MAX(line_descent, descent);
From e66003b09af99c7c1165ac8a2fc739ba49b63fdc Mon Sep 17 00:00:00 2001
From: jfons
Date: Thu, 24 Feb 2022 13:15:41 +0100
Subject: [PATCH 05/10] Upgrade stb_rect_pack to 1.01
Enables large rectangle support by default.
(cherry picked from commit 0395b5e41494fa2a69ada4020044f520b89936c7)
---
thirdparty/README.md | 4 +--
thirdparty/stb_rect_pack/stb_rect_pack.h | 35 ++++++++++--------------
2 files changed, 17 insertions(+), 22 deletions(-)
diff --git a/thirdparty/README.md b/thirdparty/README.md
index fbd597c1e29..0d7c55c6e62 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -364,8 +364,8 @@ Collection of single-file libraries used in Godot components.
* Modifications: use `const char*` instead of `char*` for input string
- `stb_rect_pack.h`
* Upstream: https://github.com/nothings/stb
- * Version: 1.00
- * License: Public Domain (Unlicense) or MIT
+ * Version: 1.01 (af1a5bc352164740c1cc1354942b1c6b72eacb8a, 2021)
+ * License: Public Domain or Unlicense or MIT
- `stb_vorbis.c`
* Upstream: https://github.com/nothings/stb
* Version: 1.20 (314d0a6f9af5af27e585336eecea333e95c5a2d8, 2020)
diff --git a/thirdparty/stb_rect_pack/stb_rect_pack.h b/thirdparty/stb_rect_pack/stb_rect_pack.h
index 3336fe7395b..4713661a44a 100644
--- a/thirdparty/stb_rect_pack/stb_rect_pack.h
+++ b/thirdparty/stb_rect_pack/stb_rect_pack.h
@@ -1,9 +1,15 @@
-// stb_rect_pack.h - v1.00 - public domain - rectangle packing
+// stb_rect_pack.h - v1.01 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
// Does not do rotation.
//
+// Before #including,
+//
+// #define STB_RECT_PACK_IMPLEMENTATION
+//
+// in the file that you want to have the implementation.
+//
// Not necessarily the awesomest packing method, but better than
// the totally naive one in stb_truetype (which is primarily what
// this is meant to replace).
@@ -35,6 +41,7 @@
//
// Version history:
//
+// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
// 0.99 (2019-02-07) warning fixes
// 0.11 (2017-03-03) return packing success/fail result
@@ -75,11 +82,10 @@ typedef struct stbrp_context stbrp_context;
typedef struct stbrp_node stbrp_node;
typedef struct stbrp_rect stbrp_rect;
-#ifdef STBRP_LARGE_RECTS
typedef int stbrp_coord;
-#else
-typedef unsigned short stbrp_coord;
-#endif
+
+#define STBRP__MAXVAL 0x7fffffff
+// Mostly for internal use, but this is the maximum supported coordinate value.
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
// Assign packed locations to rectangles. The rectangles are of type
@@ -209,8 +215,10 @@ struct stbrp_context
#ifdef _MSC_VER
#define STBRP__NOTUSED(v) (void)(v)
+#define STBRP__CDECL __cdecl
#else
#define STBRP__NOTUSED(v) (void)sizeof(v)
+#define STBRP__CDECL
#endif
enum
@@ -253,9 +261,6 @@ STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_ou
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
{
int i;
-#ifndef STBRP_LARGE_RECTS
- STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
-#endif
for (i=0; i < num_nodes-1; ++i)
nodes[i].next = &nodes[i+1];
@@ -274,11 +279,7 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height,
context->extra[0].y = 0;
context->extra[0].next = &context->extra[1];
context->extra[1].x = (stbrp_coord) width;
-#ifdef STBRP_LARGE_RECTS
context->extra[1].y = (1<<30);
-#else
- context->extra[1].y = 65535;
-#endif
context->extra[1].next = NULL;
}
@@ -520,7 +521,7 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i
return res;
}
-static int rect_height_compare(const void *a, const void *b)
+static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
@@ -531,19 +532,13 @@ static int rect_height_compare(const void *a, const void *b)
return (p->w > q->w) ? -1 : (p->w < q->w);
}
-static int rect_original_order(const void *a, const void *b)
+static int STBRP__CDECL rect_original_order(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
}
-#ifdef STBRP_LARGE_RECTS
-#define STBRP__MAXVAL 0xffffffff
-#else
-#define STBRP__MAXVAL 0xffff
-#endif
-
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
{
int i, all_rects_packed = 1;
From 824eaabd7b5baa513227da34ae237110e830de58 Mon Sep 17 00:00:00 2001
From: Hugo Locurcio
Date: Fri, 25 Feb 2022 02:32:20 +0100
Subject: [PATCH 06/10] Print every file exported with `PCKPacker.flush()`s
verbose parameter
Previously, only one line per 100 files was printed.
This also refactors the print statement to use Godot methods and
make it more informative overall.
(cherry picked from commit 8e57e5dc6a22d3e114816be3806c7499824003df)
---
core/io/pck_packer.cpp | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index ed5c9a84f29..68e2f1050bf 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -154,13 +154,11 @@ Error PCKPacker::flush(bool p_verbose) {
src->close();
memdelete(src);
count += 1;
- if (p_verbose && files.size() > 0) {
- if (count % 100 == 0) {
- printf("%i/%i (%.2f)\r", count, files.size(), float(count) / files.size() * 100);
- fflush(stdout);
- };
- };
- };
+ const int file_num = files.size();
+ if (p_verbose && (file_num > 0)) {
+ print_line(vformat("[%d/%d - %d%%] PCKPacker flush: %s -> %s", count, file_num, float(count) / file_num * 100, files[i].src_path, files[i].path));
+ }
+ }
if (p_verbose) {
printf("\n");
From 7e07d4781a934979c62670bcb7b1f1f4347d5bb0 Mon Sep 17 00:00:00 2001
From: Haoyu Qiu
Date: Mon, 28 Feb 2022 16:00:45 +0800
Subject: [PATCH 07/10] Fix AnimatedSprite infinite loop
(cherry picked from commit 3a439a9c0378d0c6f7d8ce67084863abbe4e87bc)
---
scene/2d/animated_sprite.cpp | 10 +++++-----
scene/3d/sprite_3d.cpp | 10 +++++-----
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index 2fb70038bfa..f18265ba8d9 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -364,14 +364,14 @@ void AnimatedSprite::_notification(int p_what) {
return;
}
- float speed = frames->get_animation_speed(animation) * speed_scale;
- if (speed == 0) {
- return; //do nothing
- }
-
float remaining = get_process_delta_time();
while (remaining) {
+ float speed = frames->get_animation_speed(animation) * speed_scale;
+ if (speed == 0) {
+ return; //do nothing
+ }
+
if (timeout <= 0) {
timeout = _get_frame_duration();
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index f0fbcfd332b..5633f9c4cd6 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -980,14 +980,14 @@ void AnimatedSprite3D::_notification(int p_what) {
return;
}
- float speed = frames->get_animation_speed(animation);
- if (speed == 0) {
- return; //do nothing
- }
-
float remaining = get_process_delta_time();
while (remaining) {
+ float speed = frames->get_animation_speed(animation);
+ if (speed == 0) {
+ return; // Do nothing.
+ }
+
if (timeout <= 0) {
timeout = 1.0 / speed;
From e3cd47f6ccd34823c8de63393b21fb53958304fc Mon Sep 17 00:00:00 2001
From: Sergey Minakov
Date: Sat, 26 Feb 2022 23:18:28 +0300
Subject: [PATCH 08/10] [iOS] Fix multitouch not working correctly
(cherry picked from commit 15ef056997190b288d0951ba5cc6414ce3f780a6)
---
platform/iphone/godot_view.mm | 2 ++
1 file changed, 2 insertions(+)
diff --git a/platform/iphone/godot_view.mm b/platform/iphone/godot_view.mm
index dc6623cb531..5cf914176d0 100644
--- a/platform/iphone/godot_view.mm
+++ b/platform/iphone/godot_view.mm
@@ -145,6 +145,8 @@ static const int max_touches = 8;
[self initTouches];
+ self.multipleTouchEnabled = YES;
+
// Configure and start accelerometer
if (!self.motionManager) {
self.motionManager = [[CMMotionManager alloc] init];
From 56fd92ca76afa5b91bca22c483b983bc174d2d77 Mon Sep 17 00:00:00 2001
From: Haoyu Qiu
Date: Tue, 1 Mar 2022 17:59:37 +0800
Subject: [PATCH 09/10] Fix `UndoRedo::create_action()` invalid memory usage
(cherry picked from commit b00b7f9b7c2af2d9682dd13e892c7f0d5cfcdac8)
---
core/undo_redo.cpp | 45 +++++++++++++++++----------------------------
core/undo_redo.h | 2 ++
2 files changed, 19 insertions(+), 28 deletions(-)
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp
index fdb6ece905d..c9e1211ea55 100644
--- a/core/undo_redo.cpp
+++ b/core/undo_redo.cpp
@@ -33,6 +33,20 @@
#include "core/os/os.h"
#include "core/resource.h"
+void UndoRedo::Operation::delete_reference() {
+ if (type != Operation::TYPE_REFERENCE) {
+ return;
+ }
+ if (ref.is_valid()) {
+ ref.unref();
+ } else {
+ Object *obj = ObjectDB::get_instance(object);
+ if (obj) {
+ memdelete(obj);
+ }
+ }
+}
+
void UndoRedo::_discard_redo() {
if (current_action == actions.size() - 1) {
return;
@@ -40,16 +54,7 @@ void UndoRedo::_discard_redo() {
for (int i = current_action + 1; i < actions.size(); i++) {
for (List::Element *E = actions.write[i].do_ops.front(); E; E = E->next()) {
- if (E->get().type == Operation::TYPE_REFERENCE) {
- if (E->get().ref.is_valid()) {
- E->get().ref.unref();
- } else {
- Object *obj = ObjectDB::get_instance(E->get().object);
- if (obj) {
- memdelete(obj);
- }
- }
- }
+ E->get().delete_reference();
}
//ERASE do data
}
@@ -72,14 +77,7 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
List::Element *E = actions.write[current_action + 1].do_ops.front();
while (E) {
- if (E->get().type == Operation::TYPE_REFERENCE) {
- Object *obj = ObjectDB::get_instance(E->get().object);
-
- if (obj) {
- memdelete(obj);
- }
- }
-
+ E->get().delete_reference();
E = E->next();
actions.write[current_action + 1].do_ops.pop_front();
}
@@ -224,16 +222,7 @@ void UndoRedo::_pop_history_tail() {
}
for (List::Element *E = actions.write[0].undo_ops.front(); E; E = E->next()) {
- if (E->get().type == Operation::TYPE_REFERENCE) {
- if (E->get().ref.is_valid()) {
- E->get().ref.unref();
- } else {
- Object *obj = ObjectDB::get_instance(E->get().object);
- if (obj) {
- memdelete(obj);
- }
- }
- }
+ E->get().delete_reference();
}
actions.remove(0);
diff --git a/core/undo_redo.h b/core/undo_redo.h
index 517f12b4a68..ae9cab1f187 100644
--- a/core/undo_redo.h
+++ b/core/undo_redo.h
@@ -64,6 +64,8 @@ private:
ObjectID object;
String name;
Variant args[VARIANT_ARG_MAX];
+
+ void delete_reference();
};
struct Action {
From c63ab664d282bef5d123229993e834d0da229317 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Verschelde?=
Date: Wed, 2 Mar 2022 00:11:33 +0100
Subject: [PATCH 10/10] Revert "PitchShift effect quality and performance
tweaks for different pitch scale values"
(cherry picked from commit dae0135ae53d538e6ede74e0b04142934bd655f1)
---
.../effects/audio_effect_pitch_shift.cpp | 96 +++++++------------
.../audio/effects/audio_effect_pitch_shift.h | 39 ++++----
2 files changed, 55 insertions(+), 80 deletions(-)
diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp
index 6e9f92c5513..f97d8ef22ef 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.cpp
+++ b/servers/audio/effects/audio_effect_pitch_shift.cpp
@@ -74,7 +74,7 @@
*
*****************************************************************************/
-void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int64_t fftFrameSize, int64_t osamp, float sampleRate, float *indata, float *outdata,int stride) {
+void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long fftFrameSize, long osamp, float sampleRate, float *indata, float *outdata,int stride) {
/*
@@ -85,32 +85,19 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6
*/
double magn, phase, tmp, window, real, imag;
- double freqPerBin, expct, reciprocalFftFrameSize;
- int64_t i,k, qpd, index, inFifoLatency, stepSize, fftFrameSize2;
+ double freqPerBin, expct;
+ long i,k, qpd, index, inFifoLatency, stepSize, fftFrameSize2;
/* set up some handy variables */
fftFrameSize2 = fftFrameSize/2;
- reciprocalFftFrameSize = 1./fftFrameSize;
stepSize = fftFrameSize/osamp;
- freqPerBin = reciprocalFftFrameSize * sampleRate;
- expct = Math_TAU * reciprocalFftFrameSize * stepSize;
+ freqPerBin = sampleRate/(double)fftFrameSize;
+ expct = 2.*Math_PI*(double)stepSize/(double)fftFrameSize;
inFifoLatency = fftFrameSize-stepSize;
- if (gRover == 0) {
- gRover = inFifoLatency;
- }
+ if (gRover == 0) { gRover = inFifoLatency;
+}
- // 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));
- }
+ /* initialize our static arrays */
/* main processing loop */
for (i = 0; i < numSampsToProcess; i++){
@@ -126,7 +113,7 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6
/* do windowing and re,im interleave */
for (k = 0; k < fftFrameSize;k++) {
- window = -.5*cos(Math_TAU * reciprocalFftFrameSize * k)+.5;
+ window = -.5*cos(2.*Math_PI*(double)k/(double)fftFrameSize)+.5;
gFFTworksp[2*k] = gInFIFO[k] * window;
gFFTworksp[2*k+1] = 0.;
}
@@ -138,7 +125,6 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6
/* this is the analysis step */
for (k = 0; k <= fftFrameSize2; k++) {
-
/* de-interlace FFT buffer */
real = gFFTworksp[2*k];
imag = gFFTworksp[2*k+1];
@@ -156,15 +142,13 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6
/* 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/Math_TAU;
+ tmp = osamp*tmp/(2.*Math_PI);
/* compute the k-th partials' true frequency */
tmp = (double)k*freqPerBin + tmp*freqPerBin;
@@ -177,8 +161,8 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6
/* ***************** PROCESSING ******************* */
/* this does the actual pitch shifting */
- memset(gSynMagn, 0, fftFrameSize*sizeof(double));
- memset(gSynFreq, 0, fftFrameSize*sizeof(double));
+ memset(gSynMagn, 0, fftFrameSize*sizeof(float));
+ memset(gSynFreq, 0, fftFrameSize*sizeof(float));
for (k = 0; k <= fftFrameSize2; k++) {
index = k*pitchShift;
if (index <= fftFrameSize2) {
@@ -202,7 +186,7 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6
tmp /= freqPerBin;
/* take osamp into account */
- tmp = Math_TAU*tmp/osamp;
+ tmp = 2.*Math_PI*tmp/osamp;
/* add the overlap phase advance back in */
tmp += (double)k*expct;
@@ -217,35 +201,33 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6
}
/* zero negative frequencies */
- for (k = fftFrameSize+2; k < 2*MAX_FRAME_LENGTH; k++) {
- gFFTworksp[k] = 0.;
- }
+ for (k = fftFrameSize+2; k < 2*fftFrameSize; 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(Math_TAU * reciprocalFftFrameSize * k)+.5;
+ window = -.5*cos(2.*Math_PI*(double)k/(double)fftFrameSize)+.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(double));
+ memmove(gOutputAccum, gOutputAccum+stepSize, fftFrameSize*sizeof(float));
/* 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(double *fftBuffer, int64_t fftFrameSize, int64_t sign)
+
+void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long 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
@@ -258,16 +240,14 @@ void SMBPitchShift::smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t sign
of the frequencies of interest is in fftBuffer[0...fftFrameSize].
*/
{
- 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);
+ float wr, wi, arg, *p1, *p2, temp;
+ float tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i;
+ long i, bitm, j, le, le2, k;
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) {
@@ -277,8 +257,7 @@ void SMBPitchShift::smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t sign
*p1 = *p2; *p2 = temp;
}
}
-
- for (k = 0, le = 2; k < logN; k++) {
+ for (k = 0, le = 2; k < (long)(log((double)fftFrameSize)/log(2.)+.5); k++) {
le <<= 1;
le2 = le>>1;
ur = 1.0;
@@ -310,14 +289,6 @@ void SMBPitchShift::smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t 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;
@@ -391,4 +362,7 @@ AudioEffectPitchShift::AudioEffectPitchShift() {
pitch_scale = 1.0;
oversampling = 4;
fft_size = FFT_SIZE_2048;
+ wet = 0.0;
+ dry = 0.0;
+ filter = false;
}
diff --git a/servers/audio/effects/audio_effect_pitch_shift.h b/servers/audio/effects/audio_effect_pitch_shift.h
index 97207a30fe0..6559752e8a7 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.h
+++ b/servers/audio/effects/audio_effect_pitch_shift.h
@@ -40,33 +40,31 @@ class SMBPitchShift {
float gInFIFO[MAX_FRAME_LENGTH];
float gOutFIFO[MAX_FRAME_LENGTH];
- 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;
+ 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;
- void smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t sign);
+ void smbFft(float *fftBuffer, long fftFrameSize, long sign);
public:
- void PitchShift(float pitchShift, int64_t numSampsToProcess, int64_t fftFrameSize, int64_t osamp, float sampleRate, float *indata, float *outdata, int stride);
+ void PitchShift(float pitchShift, long numSampsToProcess, long fftFrameSize, long 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(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;
+ 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));
}
};
@@ -103,6 +101,9 @@ public:
float pitch_scale;
int oversampling;
FFT_Size fft_size;
+ float wet;
+ float dry;
+ bool filter;
protected:
static void _bind_methods();