Work in progress
Godot documentation is being updated to reflect the latest changes in version
4.0
. Some documentation pages may
still state outdated information. This banner will tell you if you're reading one of such pages.
The contents of this page are up to date. If you can still find outdated information, please open an issue.
Custom AudioStreams¶
Introduction¶
AudioStream is the base class of all audio emitting objects. AudioStreamPlayer binds onto an AudioStream to emit PCM data into an AudioServer which manages audio drivers.
All audio resources require two audio based classes: AudioStream and AudioStreamPlayback. As a data container, AudioStream contains the resource and exposes itself to GDScript. AudioStream references its own internal custom AudioStreamPlayback which translates AudioStream into PCM data.
This guide assumes the reader knows how to create C++ modules. If not, refer to this guide Custom modules in C++.
References:¶
What for?¶
Binding external libraries (like Wwise, FMOD, etc).
Adding custom audio queues
Adding support for more audio formats
Create an AudioStream¶
An AudioStream consists of three components: data container, stream name, and an AudioStreamPlayback friend class generator. Audio data can be loaded in a number of ways such as with an internal counter for a tone generator, internal/external buffer, or a file reference.
Some AudioStreams need to be stateless such as objects loaded from
ResourceLoader. ResourceLoader loads once and references the same
object regardless how many times load
is called on a specific resource.
Therefore, playback state must be self-contained in AudioStreamPlayback.
/* audiostream_mytone.h */
#include "core/reference.h"
#include "core/resource.h"
#include "servers/audio/audio_stream.h"
class AudioStreamMyTone : public AudioStream {
GDCLASS(AudioStreamMyTone, AudioStream)
private:
friend class AudioStreamPlaybackMyTone;
uint64_t pos;
int mix_rate;
bool stereo;
int hz;
public:
void reset();
void set_position(uint64_t pos);
virtual Ref<AudioStreamPlayback> instance_playback();
virtual String get_stream_name() const;
void gen_tone(int16_t *pcm_buf, int size);
virtual float get_length() const { return 0; } // if supported, otherwise return 0
AudioStreamMyTone();
protected:
static void _bind_methods();
};
/* audiostream_mytone.cpp */
#include "audiostream_mytone.h"
AudioStreamMyTone::AudioStreamMyTone()
: mix_rate(44100), stereo(false), hz(639) {
}
Ref<AudioStreamPlayback> AudioStreamMyTone::instance_playback() {
Ref<AudioStreamPlaybackMyTone> talking_tree;
talking_tree.instantiate();
talking_tree->base = Ref<AudioStreamMyTone>(this);
return talking_tree;
}
String AudioStreamMyTone::get_stream_name() const {
return "MyTone";
}
void AudioStreamMyTone::reset() {
set_position(0);
}
void AudioStreamMyTone::set_position(uint64_t p) {
pos = p;
}
void AudioStreamMyTone::gen_tone(int16_t *pcm_buf, int size) {
for (int i = 0; i < size; i++) {
pcm_buf[i] = 32767.0 * sin(2.0 * Math_PI *