Skip to content

Index out of bound crash when creating a custom audio effect #1075

Open
@lucasrafael98

Description

@lucasrafael98

Hi, I've been having a crash I can't figure out how to debug. I'm trying to use the base classes to implement a custom audio effect, and everything compiles and links until I try to add this empty effect to the audio bus. The following happens:

ERROR: Required virtual method CustomAudioEffect::_instantiate must be overridden before calling.
   at: _gdvirtual__instantiate_call (servers/audio/audio_effect.h:57)

================================================================
handle_crash: Program crashed with signal 11
Engine version: Godot Engine v4.0.1.stable.flathub (cacf49999e3fb37281d66cc591ca8bebc5712d4d)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
ERROR: FATAL: Index p_index = 1 is out of bounds (size() = 0).
   at: get (./core/templates/cowdata.h:155)

================================================================
handle_crash: Program crashed with signal 4
Engine version: Godot Engine v4.0.1.stable.flathub (cacf49999e3fb37281d66cc591ca8bebc5712d4d)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
ERROR: FATAL: Index p_index = 1 is out of bounds (size() = 0).
   at: get (./core/templates/cowdata.h:155)

I don't really know why Godot thinks CustomAudioEffect::_instantiate() needs to be overriden since it's a non-virtual override of AudioEffect, and I don't have any code that handles arrays (presumably the out-of-bound errors are in some internal stuff).

Here's the code (sorry, this is the shortest I could get it to be):

// custom_effect.hpp

#ifndef CUSTOM_EFFECT_HPP
#define CUSTOM_EFFECT_HPP

#include <godot_cpp/classes/audio_effect.hpp>
#include <godot_cpp/classes/audio_effect_instance.hpp>
#include <godot_cpp/classes/audio_frame.hpp>

using namespace godot;

class CustomAudioEffect;

class CustomAudioEffectInstance : public AudioEffectInstance {
	GDCLASS(CustomAudioEffectInstance, AudioEffectInstance)
	friend class CustomAudioEffect;
	Ref<CustomAudioEffect> base;

protected:
	static void _bind_methods();

public:
	void _process(const void *src_buffer, AudioFrame *dst_buffer, int32_t frame_count) override;
	bool _process_silence() const override;
};

class CustomAudioEffect : public AudioEffect {
	GDCLASS(CustomAudioEffect, AudioEffect)
	friend class CustomAudioEffectInstance;

protected:
	static void _bind_methods();

public:
	Ref<AudioEffectInstance> _instantiate() override;
	CustomAudioEffect();
};

#endif

// -----------------
// custom_effect.cpp

#include "custom_effect.hpp"

void CustomAudioEffectInstance::_process(const void *src_buffer, AudioFrame *dst_buffer, int32_t frame_count) {
}

bool CustomAudioEffectInstance::_process_silence() const {
	return false;
}

void CustomAudioEffectInstance::_bind_methods() {
}

void CustomAudioEffect::_bind_methods() {
}

Ref<AudioEffectInstance> CustomAudioEffect::_instantiate() {
	Ref<CustomAudioEffectInstance> ins;
	ins.instantiate();
	ins->base = Ref<CustomAudioEffect>(this);
	return ins;
}

CustomAudioEffect::CustomAudioEffect() {
}

// ------------
// register_types.hpp

#ifndef GDEXAMPLE_REGISTER_TYPES_H
#define GDEXAMPLE_REGISTER_TYPES_H

void init_fs_exts();
void uninit_fs_exts();

#endif // GDEXAMPLE_REGISTER_TYPES_H

// ------------
// register_types.cpp

#include "register_types.hpp"

#include "custom_effect.hpp"

#include <gdextension_interface.h>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/defs.hpp>
#include <godot_cpp/godot.hpp>

using namespace godot;

void init_fs_exts(ModuleInitializationLevel p_level) {
	if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
		return;
	}

	ClassDB::register_class<CustomAudioEffect>();
}

void uninit_fs_exts(ModuleInitializationLevel p_level) {
	if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
		return;
	}
}

extern "C" {
// Initialization.
GDExtensionBool GDE_EXPORT lib_init(const GDExtensionInterface *p_interface, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
	godot::GDExtensionBinding::InitObject init_obj(p_interface, p_library, r_initialization);

	init_obj.register_initializer(init_fs_exts);
	init_obj.register_terminator(uninit_fs_exts);
	init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);

	return init_obj.init();
}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis has been identified as a bugcrashtopic:gdextensionThis relates to the new Godot 4 extension implementation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions