Skip to content

Commit

Permalink
cleanup formatting; update audio plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
ppiecuch committed Oct 12, 2023
1 parent 33ba2cf commit 8582b14
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 30 deletions.
31 changes: 15 additions & 16 deletions editor/audio_stream_preview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
#include "audio_stream_preview.h"

#include "core/os/keyboard.h"
#include "scene/gui/box_container.h"
#include "editor/editor_settings.h"
#include "editor/editor_scale.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "scene/gui/box_container.h"

// BEGIN AudioStreamPreview

Expand Down Expand Up @@ -106,7 +106,6 @@ AudioStreamPreview::AudioStreamPreview() {

// END AudioStreamPreview


// BEGIN AudioStreamPreviewGenerator

void AudioStreamPreviewGenerator::_update_emit(ObjectID p_id) {
Expand Down Expand Up @@ -256,20 +255,21 @@ AudioStreamPreviewGenerator::AudioStreamPreviewGenerator() {

// END AudioStreamPreviewGenerator


// BEGIN AudioStreamPlayerControl

void AudioStreamPlayerControl::_play() {
if (_player->is_playing()) {
// '_pausing' variable indicates that we want to pause the audio player, not stop it. See '_on_finished()'.
_pausing = true;
_player->stop();
_play_button->set_icon(get_icon("MainPlay", "EditorIcons"));
set_process(false);
} else {
_player->play(_current);
_play_button->set_icon(get_icon("Pause", "EditorIcons"));
set_process(true);
if (!stream.is_null()) {
if (_player->is_playing()) {
// '_pausing' variable indicates that we want to pause the audio player, not stop it. See '_on_finished()'.
_pausing = true;
_player->stop();
_play_button->set_icon(get_icon("MainPlay", "EditorIcons"));
set_process(false);
} else {
_player->play(_current);
_play_button->set_icon(get_icon("Pause", "EditorIcons"));
set_process(true);
}
}
}

Expand Down Expand Up @@ -371,7 +371,6 @@ void AudioStreamPlayerControl::_on_input_indicator(Ref<InputEvent> p_event) {
}
}


void AudioStreamPlayerControl::_seek_to(real_t p_x) {
_current = p_x / _preview->get_rect().size.x * stream->get_length();
_current = CLAMP(_current, 0, stream->get_length());
Expand Down
76 changes: 76 additions & 0 deletions modules/gdextensions/common/gd_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,80 @@ _FORCE_INLINE_ static uint8_t g_alpha(uint32_t rgb) { return rgb >> 24; }
_FORCE_INLINE_ static uint32_t g_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); }
_FORCE_INLINE_ static uint8_t g_gray(uint8_t r, uint8_t g, uint8_t b) { return (r * 11 + g * 16 + b * 5) / 32; } // convert R,G,B to gray 0..255

// Passthrough Script for dynamic scripting

class PassthroughScriptInstance : public PlaceHolderScriptInstance {
public:
virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
return get_owner()->call(p_method, p_args, p_argcount, r_error);
}
};

template <typename InstanceBaseClass, typename Receiver>
class PassthroughScript : public Script {
Receiver *recv;

#ifdef TOOLS_ENABLED
Set<PlaceHolderScriptInstance *> placeholders;
virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {
placeholders.erase(p_placeholder);
}
#endif

public:
void remove_instance(Object *p_object) {}
virtual bool can_instance() const { return false; }

virtual StringName get_instance_base_type() const { return InstanceBaseClass::get_class_static(); }
virtual ScriptInstance *instance_create(Object *p_this) { return nullptr; }
virtual bool instance_has(const Object *p_this) const { return false; }

virtual PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) {
#ifdef TOOLS_ENABLED
PlaceHolderScriptInstance *sins = memnew(PlaceHolderScriptInstance(nullptr, Ref<Script>(this), recv));
placeholders.insert(sins);
return sins;
#else
return nullptr;
#endif
}

virtual bool has_source_code() const { return false; }
virtual String get_source_code() const { return ""; }
virtual void set_source_code(const String &p_code) {}
virtual Error reload(bool p_keep_state = false) { return OK; }

virtual bool is_tool() const { return false; }
virtual bool is_valid() const { return true; }

virtual bool inherits_script(const Ref<Script> &p_script) const { return false; }

virtual String get_node_type() const { return ""; }
virtual ScriptLanguage *get_language() const { return nullptr; }

// Be carfull with possible recursion

virtual Ref<Script> get_base_script() const { return Ref<Script>(); }
virtual bool has_method(const StringName &p_method) const { return recv->has_method(p_method); }
virtual MethodInfo get_method_info(const StringName &p_method) const {
List<MethodInfo> methods;
recv->get_method_list(&methods);
for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
if (E->get().name == p_method) {
return E->get();
}
}
return MethodInfo();
}
virtual bool has_script_signal(const StringName &p_signal) const { return recv->has_signal(p_signal); }
virtual void get_script_signal_list(List<MethodInfo> *r_signals) const { recv->get_signal_list(r_signals); }
virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const { return false; }
virtual void get_script_method_list(List<MethodInfo> *p_list) const { recv->get_method_list(p_list); }
virtual void get_script_property_list(List<PropertyInfo> *p_list) const { recv->get_property_list(p_list); }
virtual void update_exports() {}

void set_receiver(Receiver *p_recv) { recv = p_recv; }
Receiver *get_receiver() const { return recv; }
};

#endif // GD_CORE_H
107 changes: 98 additions & 9 deletions modules/gdextensions/submodules/editor/power_station_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ PSState _ps_defaults = {
0,
};

typedef void PSPercentCallback(float percent, void *userdata);

typedef struct _vector3 {
double x, y, z;
} vector3;

typedef void PSPercentCallback(float percent, void *userdata);

typedef struct _PSMetalObjNode {
int anchor;
vector3 pos;
Expand Down Expand Up @@ -114,16 +114,15 @@ PSMetalObj *ps_metal_obj_new_plane(int length, int width, double tension);
PSMetalObj *ps_metal_obj_new_hypercube(int dimensions, int size, double tension);

static void ps_metal_obj_perturb(PSMetalObj *obj, double speed, double damp);

int save_pres(PSPhysMod *model, const char *fname, char **errmsg);
int load_pres(PSPhysMod *model, const char *fname, char **errmsg);

static size_t ps_metal_obj_render(int rate, PSMetalObj *obj, int innode, int outnode, double speed, double damp, int compress, double velocity, int len, double *samples, PSPercentCallback *cb, double att, void *userdata);

size_t ps_metal_obj_render_tube(int rate, int height, int circum, double tension, double speed, double damp, int compress, double velocity, int len, double *samples, PSPercentCallback *cb, double att, void *userdata);
size_t ps_metal_obj_render_rod(int rate, int length, double tension, double speed, double damp, int compress, double velocity, int len, double *samples, PSPercentCallback *cb, double att, void *userdata);
size_t ps_metal_obj_render_plane(int rate, int length, int width, double tension, double speed, double damp, int compress, double velocity, int len, double *samples, PSPercentCallback *cb, double att, void *userdata);

int save_pres(PSPhysMod *model, const char *fname, char **errmsg);
int load_pres(PSPhysMod *model, const char *fname, char **errmsg);

// Utility functions.

_FORCE_INLINE_ int16_t double_to_s16(double d) {
Expand Down Expand Up @@ -412,6 +411,76 @@ static void ps_metal_obj_perturb(PSMetalObj *obj, double speed, double damp) {
}
}

// Now len means _maximal_ lenght if the given attenuation will not be reached;
// for disabling stopping at given attenuation, use attenuation = 0.0.
// Attenuation is given in dB, att = 60.0 means render will be stopped after
// the mean amplitude reach the value of -60 dB.

static size_t ps_metal_obj_render(int rate, PSMetalObj *obj, int innode, int outnode, double speed, double damp, int compress, double velocity, int len, double *samples, PSPercentCallback *cb, double att, void *userdata) {
double stasis;
double sample;

if (compress) {
stasis = obj->nodes[outnode]->pos.z;
obj->nodes[innode]->pos.z += velocity;
} else {
stasis = obj->nodes[outnode]->pos.x;
obj->nodes[innode]->pos.x += velocity;
}

damp = Math::pow(0.5, 1.0 / (damp * rate));

double curr_att = 0, hipass = 0, lowpass = 0, maxamp = 0;
double hipass_coeff = Math::pow(0.5, 5.0 / rate);
double lowpass_coeff = 1 - 20.0 / rate; // 50 ms integrator
double maxvol = 0.001;
size_t real_len = 0;
for (int i = 0; i < len; i++) {
ps_metal_obj_perturb(obj, speed, damp);
if (compress) {
sample = obj->nodes[outnode]->pos.z - stasis;
} else {
sample = obj->nodes[outnode]->pos.x - stasis;
}
hipass = hipass_coeff * hipass + (1 - hipass_coeff) * sample;
samples[i] = sample - hipass;
if (Math::abs(samples[i]) > maxvol) {
maxvol = Math::abs(samples[i]);
}
lowpass = lowpass_coeff * lowpass + (1 - lowpass_coeff) * Math::abs(samples[i]);
if (maxamp < lowpass) {
maxamp = lowpass;
}
if (att < 0) {
if (maxamp > 0) {
curr_att = 20 * Math::log10(lowpass / maxamp);
}
if (!(i & 1023)) {
if (cb != nullptr) {
float p1 = ((float)i) / len;
float p2 = curr_att / att;
cb(MAX(p1, p2), userdata);
}
}
if (curr_att <= att) {
break;
}
} else {
if (!(i & 1023)) {
if (cb != nullptr)
cb(((float)i) / len, userdata);
}
}
real_len++;
}

maxvol = 1.0 / maxvol;
for (int i = 0; i < real_len; i++) {
samples[i] *= maxvol;
}
return real_len;
}

size_t ps_metal_obj_render_tube(int rate, int height, int circum, double tension, double speed, double damp, int compress, double velocity, int len, double *samples, PSPercentCallback *cb, double att, void *userdata) {
PSMetalObj *obj = ps_metal_obj_new_tube(height, circum, tension);
int innode = circum + circum / 2;
Expand All @@ -421,6 +490,24 @@ size_t ps_metal_obj_render_tube(int rate, int height, int circum, double tension
return lgth;
}

size_t ps_metal_obj_render_rod(int rate, int length, double tension, double speed, double damp, int compress, double velocity, int len, double *samples, PSPercentCallback *cb, double att, void *userdata) {
PSMetalObj *obj = ps_metal_obj_new_rod(length, tension);
int innode = 1;
int outnode = length - 2;
size_t lgth = ps_metal_obj_render(rate, obj, innode, outnode, speed, damp, compress, velocity, len, samples, cb, att, userdata);
ps_metal_obj_free(obj);
return lgth;
}

size_t ps_metal_obj_render_plane(int rate, int length, int width, double tension, double speed, double damp, int compress, double velocity, int len, double *samples, PSPercentCallback *cb, double att, void *userdata) {
PSMetalObj *obj = ps_metal_obj_new_plane(length, width, tension);
int innode = 1;
int outnode = (length - 1) * width - 1;
size_t lgth = ps_metal_obj_render(rate, obj, innode, outnode, speed, damp, compress, velocity, len, samples, cb, att, userdata);
ps_metal_obj_free(obj);
return lgth;
}

// Callbacks functions.

#define SAMPLE_RATE 44100
Expand All @@ -431,9 +518,9 @@ static void percent_callback(float p, void *userdata) {
s->progress = p;
}

static void do_render(PSState *ps) {
static bool do_render(PSState *ps) {
LocalVector<double> data(SAMPLE_RATE * ps->sample_length);
double decay = ps->decay_is_used ? ps->decay_value : 0;
const double decay = ps->decay_is_used ? ps->decay_value : 0;

size_t size = data.size();
switch (ps->obj_type) {
Expand All @@ -448,10 +535,12 @@ static void do_render(PSState *ps) {
} break;
}

ERR_FAIL_COND(size > data.size());
ERR_FAIL_COND_V(size > data.size(), false);

ps->samples.resize(data.size());
for (int i = 0; i < size; i++) {
ps->samples[i] = double_to_s16(data[i]);
}

return true;
}
32 changes: 27 additions & 5 deletions modules/gdextensions/submodules/editor/power_station_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
// Power Station Glib PhyMod Library
// Copyright (c) 2000 David A. Bartold

#ifndef __PS_PHYMOD_H_
#define __PS_PHYMOD_H_

#include <stdio.h>
#ifndef _POWER_STATION_PLUGIN_H_
#define _POWER_STATION_PLUGIN_H_

#include "core/int_types.h"
#include "core/local_vector.h"
#include "editor/editor_plugin.h"
#include "scene/gui/dialogs.h"

typedef struct _PSState {
int size;
Expand All @@ -56,4 +56,26 @@ typedef struct _PSState {
float progress;
} PSState;

#endif
/// Godot editor plugin

class PowerStationEditorPlugin : public EditorPlugin {
GDCLASS(PowerStationEditorPlugin, EditorPlugin)

EditorNode *editor;

void add_icons_menu_item(const String &p_name, const String &p_callback);
void remove_icons_menu_item(const String &p_name);

void _on_show_ps_editor_pressed(Variant p_null);

protected:
static void _bind_methods();
void _notification(int p_what);

public:
void generate();

PowerStationEditorPlugin(EditorNode *p_node);
};

#endif // _POWER_STATION_PLUGIN_H_

0 comments on commit 8582b14

Please sign in to comment.