|
@@ -6,17 +6,17 @@ Custom AudioStreams
|
|
Introduction
|
|
Introduction
|
|
------------
|
|
------------
|
|
|
|
|
|
-AudioStream is the base class of all audio emitting objects.
|
|
|
|
-AudioStreamPlayer binds onto an AudioStream to emit PCM data
|
|
|
|
|
|
+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.
|
|
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
|
|
|
|
|
|
+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.
|
|
AudioStream into PCM data.
|
|
|
|
|
|
-This guide assumes the reader knows how to create C++ modules. If not, refer to this guide
|
|
|
|
|
|
+This guide assumes the reader knows how to create C++ modules. If not, refer to this guide
|
|
:ref:`doc_custom_modules_in_c++`.
|
|
:ref:`doc_custom_modules_in_c++`.
|
|
|
|
|
|
References:
|
|
References:
|
|
@@ -25,8 +25,6 @@ References:
|
|
- `servers/audio/audio_stream.h <https://github.com/godotengine/godot/blob/master/servers/audio/audio_stream.h>`__
|
|
- `servers/audio/audio_stream.h <https://github.com/godotengine/godot/blob/master/servers/audio/audio_stream.h>`__
|
|
- `scene/audio/audioplayer.cpp <https://github.com/godotengine/godot/blob/master/scene/audio/audio_player.cpp>`__
|
|
- `scene/audio/audioplayer.cpp <https://github.com/godotengine/godot/blob/master/scene/audio/audio_player.cpp>`__
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
What for?
|
|
What for?
|
|
---------
|
|
---------
|
|
|
|
|
|
@@ -37,57 +35,58 @@ What for?
|
|
Create an AudioStream
|
|
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,
|
|
|
|
|
|
+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.
|
|
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.
|
|
|
|
|
|
+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.
|
|
Therefore, playback state must be self contained in AudioStreamPlayback.
|
|
|
|
|
|
-
|
|
|
|
.. code:: cpp
|
|
.. code:: cpp
|
|
|
|
|
|
/* audiostream_mytone.h */
|
|
/* audiostream_mytone.h */
|
|
|
|
|
|
- #include "reference.h"
|
|
|
|
- #include "resource.h"
|
|
|
|
- #include "servers/audio/audio_stream.h
|
|
|
|
|
|
+ #include "core/reference.h"
|
|
|
|
+ #include "core/resource.h"
|
|
|
|
+ #include "servers/audio/audio_stream.h"
|
|
|
|
|
|
class AudioStreamMyTone : public AudioStream {
|
|
class AudioStreamMyTone : public AudioStream {
|
|
GDCLASS(AudioStreamMyTone, AudioStream)
|
|
GDCLASS(AudioStreamMyTone, AudioStream)
|
|
|
|
+
|
|
private:
|
|
private:
|
|
friend class AudioStreamPlaybackMyTone;
|
|
friend class AudioStreamPlaybackMyTone;
|
|
uint64_t pos;
|
|
uint64_t pos;
|
|
int mix_rate;
|
|
int mix_rate;
|
|
bool stereo;
|
|
bool stereo;
|
|
int hz;
|
|
int hz;
|
|
|
|
+
|
|
public:
|
|
public:
|
|
void reset();
|
|
void reset();
|
|
void set_position(uint64_t pos);
|
|
void set_position(uint64_t pos);
|
|
virtual Ref<AudioStreamPlayback> instance_playback();
|
|
virtual Ref<AudioStreamPlayback> instance_playback();
|
|
virtual String get_stream_name() const;
|
|
virtual String get_stream_name() const;
|
|
- void gen_tone(int16_t *, int frames);
|
|
|
|
- virtual float get_length() const { return 0; } //if supported, otherwise return 0
|
|
|
|
|
|
+ void gen_tone(int16_t *pcm_buf, int size);
|
|
|
|
+ virtual float get_length() const { return 0; } // if supported, otherwise return 0
|
|
AudioStreamMyTone();
|
|
AudioStreamMyTone();
|
|
|
|
|
|
protected:
|
|
protected:
|
|
static void _bind_methods();
|
|
static void _bind_methods();
|
|
};
|
|
};
|
|
|
|
|
|
-
|
|
|
|
.. code:: cpp
|
|
.. code:: cpp
|
|
|
|
|
|
/* audiostream_mytone.cpp */
|
|
/* audiostream_mytone.cpp */
|
|
|
|
+
|
|
|
|
+ #include "audiostream_mytone.h"
|
|
|
|
+
|
|
AudioStreamMyTone::AudioStreamMyTone()
|
|
AudioStreamMyTone::AudioStreamMyTone()
|
|
- : mix_rate(44100), stereo(false), hz(639) {
|
|
|
|
|
|
+ : mix_rate(44100), stereo(false), hz(639) {
|
|
}
|
|
}
|
|
|
|
|
|
- Ref<AudioStreamPlayback> AudioStreamMyTone::instance_playback(){
|
|
|
|
|
|
+ Ref<AudioStreamPlayback> AudioStreamMyTone::instance_playback() {
|
|
Ref<AudioStreamPlaybackMyTone> talking_tree;
|
|
Ref<AudioStreamPlaybackMyTone> talking_tree;
|
|
talking_tree.instance();
|
|
talking_tree.instance();
|
|
talking_tree->base = Ref<AudioStreamMyTone>(this);
|
|
talking_tree->base = Ref<AudioStreamMyTone>(this);
|
|
@@ -103,16 +102,15 @@ Therefore, playback state must be self contained in AudioStreamPlayback.
|
|
void AudioStreamMyTone::set_position(uint64_t p) {
|
|
void AudioStreamMyTone::set_position(uint64_t p) {
|
|
pos = 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*double(pos+i)/(double(mix_rate)/double(hz)));
|
|
|
|
|
|
+ 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 * double(pos + i) / (double(mix_rate) / double(hz)));
|
|
}
|
|
}
|
|
pos += size;
|
|
pos += size;
|
|
}
|
|
}
|
|
- void AudioStreamMyTone::_bind_methods(){
|
|
|
|
|
|
+ void AudioStreamMyTone::_bind_methods() {
|
|
ClassDB::bind_method(D_METHOD("reset"), &AudioStreamMyTone::reset);
|
|
ClassDB::bind_method(D_METHOD("reset"), &AudioStreamMyTone::reset);
|
|
ClassDB::bind_method(D_METHOD("get_stream_name"), &AudioStreamMyTone::get_stream_name);
|
|
ClassDB::bind_method(D_METHOD("get_stream_name"), &AudioStreamMyTone::get_stream_name);
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
References:
|
|
References:
|
|
@@ -124,23 +122,24 @@ References:
|
|
Create an AudioStreamPlayback
|
|
Create an AudioStreamPlayback
|
|
-----------------------------
|
|
-----------------------------
|
|
|
|
|
|
-AudioStreamPlayer uses ``mix`` callback to obtain PCM data. The callback must match sample rate and fill the buffer.
|
|
|
|
|
|
+AudioStreamPlayer uses ``mix`` callback to obtain PCM data. The callback must match sample rate and fill the buffer.
|
|
|
|
|
|
Since AudioStreamPlayback is controlled by the audio thread, i/o and dynamic memory allocation are forbidden.
|
|
Since AudioStreamPlayback is controlled by the audio thread, i/o and dynamic memory allocation are forbidden.
|
|
|
|
|
|
.. code:: cpp
|
|
.. code:: cpp
|
|
|
|
|
|
/* audiostreamplayer_mytone.h */
|
|
/* audiostreamplayer_mytone.h */
|
|
- #include "reference.h"
|
|
|
|
- #include "resource.h"
|
|
|
|
- #include "servers/audio/audio_stream.h"
|
|
|
|
|
|
|
|
|
|
+ #include "core/reference.h"
|
|
|
|
+ #include "core/resource.h"
|
|
|
|
+ #include "servers/audio/audio_stream.h"
|
|
|
|
|
|
class AudioStreamPlaybackMyTone : public AudioStreamPlayback {
|
|
class AudioStreamPlaybackMyTone : public AudioStreamPlayback {
|
|
GDCLASS(AudioStreamPlaybackMyTone, AudioStreamPlayback)
|
|
GDCLASS(AudioStreamPlaybackMyTone, AudioStreamPlayback)
|
|
friend class AudioStreamMyTone;
|
|
friend class AudioStreamMyTone;
|
|
|
|
+
|
|
private:
|
|
private:
|
|
- enum{
|
|
|
|
|
|
+ enum {
|
|
PCM_BUFFER_SIZE = 4096
|
|
PCM_BUFFER_SIZE = 4096
|
|
};
|
|
};
|
|
enum {
|
|
enum {
|
|
@@ -148,34 +147,34 @@ Since AudioStreamPlayback is controlled by the audio thread, i/o and dynamic mem
|
|
MIX_FRAC_LEN = (1 << MIX_FRAC_BITS),
|
|
MIX_FRAC_LEN = (1 << MIX_FRAC_BITS),
|
|
MIX_FRAC_MASK = MIX_FRAC_LEN - 1,
|
|
MIX_FRAC_MASK = MIX_FRAC_LEN - 1,
|
|
};
|
|
};
|
|
- void * pcm_buffer;
|
|
|
|
|
|
+ void *pcm_buffer;
|
|
Ref<AudioStreamMyTone> base;
|
|
Ref<AudioStreamMyTone> base;
|
|
bool active;
|
|
bool active;
|
|
|
|
+
|
|
public:
|
|
public:
|
|
virtual void start(float p_from_pos = 0.0);
|
|
virtual void start(float p_from_pos = 0.0);
|
|
virtual void stop();
|
|
virtual void stop();
|
|
virtual bool is_playing() const;
|
|
virtual bool is_playing() const;
|
|
- virtual int get_loop_count() const; //times it looped
|
|
|
|
|
|
+ virtual int get_loop_count() const; // times it looped
|
|
virtual float get_playback_position() const;
|
|
virtual float get_playback_position() const;
|
|
virtual void seek(float p_time);
|
|
virtual void seek(float p_time);
|
|
virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames);
|
|
virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames);
|
|
- virtual float get_length() const; //if supported, otherwise return 0
|
|
|
|
|
|
+ virtual float get_length() const; // if supported, otherwise return 0
|
|
AudioStreamPlaybackMyTone();
|
|
AudioStreamPlaybackMyTone();
|
|
~AudioStreamPlaybackMyTone();
|
|
~AudioStreamPlaybackMyTone();
|
|
-
|
|
|
|
};
|
|
};
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
.. code:: cpp
|
|
.. code:: cpp
|
|
|
|
|
|
/* audiostreamplayer_mytone.cpp */
|
|
/* audiostreamplayer_mytone.cpp */
|
|
|
|
+
|
|
#include "audiostreamplayer_mytone.h"
|
|
#include "audiostreamplayer_mytone.h"
|
|
- #include "math/math_funcs.h"
|
|
|
|
- #include "print_string.h"
|
|
|
|
|
|
|
|
- AudioStreamPlaybackMyTone::AudioStreamPlaybackMyTone()
|
|
|
|
- : active(false){
|
|
|
|
|
|
+ #include "core/math/math_funcs.h"
|
|
|
|
+ #include "core/print_string.h"
|
|
|
|
+
|
|
|
|
+ AudioStreamPlaybackMyTone::AudioStreamPlaybackMyTone()
|
|
|
|
+ : active(false) {
|
|
AudioServer::get_singleton()->lock();
|
|
AudioServer::get_singleton()->lock();
|
|
pcm_buffer = AudioServer::get_singleton()->audio_data_alloc(PCM_BUFFER_SIZE);
|
|
pcm_buffer = AudioServer::get_singleton()->audio_data_alloc(PCM_BUFFER_SIZE);
|
|
zeromem(pcm_buffer, PCM_BUFFER_SIZE);
|
|
zeromem(pcm_buffer, PCM_BUFFER_SIZE);
|
|
@@ -187,33 +186,32 @@ Since AudioStreamPlayback is controlled by the audio thread, i/o and dynamic mem
|
|
pcm_buffer = NULL;
|
|
pcm_buffer = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- void AudioStreamPlaybackMyTone::stop(){
|
|
|
|
|
|
+ void AudioStreamPlaybackMyTone::stop() {
|
|
active = false;
|
|
active = false;
|
|
base->reset();
|
|
base->reset();
|
|
}
|
|
}
|
|
-
|
|
|
|
- void AudioStreamPlaybackMyTone::start(float p_from_pos){
|
|
|
|
|
|
+ void AudioStreamPlaybackMyTone::start(float p_from_pos) {
|
|
seek(p_from_pos);
|
|
seek(p_from_pos);
|
|
active = true;
|
|
active = true;
|
|
}
|
|
}
|
|
- void AudioStreamPlaybackMyTone::seek(float p_time){
|
|
|
|
|
|
+ void AudioStreamPlaybackMyTone::seek(float p_time) {
|
|
float max = get_length();
|
|
float max = get_length();
|
|
if (p_time < 0) {
|
|
if (p_time < 0) {
|
|
p_time = 0;
|
|
p_time = 0;
|
|
}
|
|
}
|
|
base->set_position(uint64_t(p_time * base->mix_rate) << MIX_FRAC_BITS);
|
|
base->set_position(uint64_t(p_time * base->mix_rate) << MIX_FRAC_BITS);
|
|
}
|
|
}
|
|
- void AudioStreamPlaybackMyTone::mix(AudioFrame *p_buffer, float p_rate, int p_frames){
|
|
|
|
|
|
+ void AudioStreamPlaybackMyTone::mix(AudioFrame *p_buffer, float p_rate, int p_frames) {
|
|
ERR_FAIL_COND(!active);
|
|
ERR_FAIL_COND(!active);
|
|
if (!active) {
|
|
if (!active) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
zeromem(pcm_buffer, PCM_BUFFER_SIZE);
|
|
zeromem(pcm_buffer, PCM_BUFFER_SIZE);
|
|
- int16_t * buf = (int16_t * )pcm_buffer;
|
|
|
|
|
|
+ int16_t *buf = (int16_t *)pcm_buffer;
|
|
base->gen_tone(buf, p_frames);
|
|
base->gen_tone(buf, p_frames);
|
|
|
|
|
|
- for(int i = 0; i < p_frames; i++){
|
|
|
|
- float sample = float(buf[i])/32767.0;
|
|
|
|
|
|
+ for(int i = 0; i < p_frames; i++) {
|
|
|
|
+ float sample = float(buf[i]) / 32767.0;
|
|
p_buffer[i] = AudioFrame(sample, sample);
|
|
p_buffer[i] = AudioFrame(sample, sample);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -230,23 +228,20 @@ Since AudioStreamPlayback is controlled by the audio thread, i/o and dynamic mem
|
|
return active;
|
|
return active;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
Resampling
|
|
Resampling
|
|
~~~~~~~~~~
|
|
~~~~~~~~~~
|
|
|
|
|
|
-
|
|
|
|
-Godot’s AudioServer currently uses 44100 Hz sample rate. When other sample rates are
|
|
|
|
-needed such as 48000, either provide one or use AudioStreamPlaybackResampled.
|
|
|
|
|
|
+Godot’s AudioServer currently uses 44100 Hz sample rate. When other sample rates are
|
|
|
|
+needed such as 48000, either provide one or use AudioStreamPlaybackResampled.
|
|
Godot provides cubic interpolation for audio resampling.
|
|
Godot provides cubic interpolation for audio resampling.
|
|
|
|
|
|
-Instead of overloading ``mix``, AudioStreamPlaybackResampled uses ``_mix_internal`` to
|
|
|
|
|
|
+Instead of overloading ``mix``, AudioStreamPlaybackResampled uses ``_mix_internal`` to
|
|
query AudioFrames and ``get_stream_sampling_rate`` to query current mix rate.
|
|
query AudioFrames and ``get_stream_sampling_rate`` to query current mix rate.
|
|
|
|
|
|
.. code:: cpp
|
|
.. code:: cpp
|
|
|
|
|
|
- #include "reference.h"
|
|
|
|
- #include "resource.h"
|
|
|
|
-
|
|
|
|
|
|
+ #include "core/reference.h"
|
|
|
|
+ #include "core/resource.h"
|
|
#include "servers/audio/audio_stream.h"
|
|
#include "servers/audio/audio_stream.h"
|
|
|
|
|
|
class AudioStreamMyToneResampled;
|
|
class AudioStreamMyToneResampled;
|
|
@@ -254,8 +249,9 @@ query AudioFrames and ``get_stream_sampling_rate`` to query current mix rate.
|
|
class AudioStreamPlaybackResampledMyTone : public AudioStreamPlaybackResampled {
|
|
class AudioStreamPlaybackResampledMyTone : public AudioStreamPlaybackResampled {
|
|
GDCLASS(AudioStreamPlaybackResampledMyTone, AudioStreamPlaybackResampled)
|
|
GDCLASS(AudioStreamPlaybackResampledMyTone, AudioStreamPlaybackResampled)
|
|
friend class AudioStreamMyToneResampled;
|
|
friend class AudioStreamMyToneResampled;
|
|
|
|
+
|
|
private:
|
|
private:
|
|
- enum{
|
|
|
|
|
|
+ enum {
|
|
PCM_BUFFER_SIZE = 4096
|
|
PCM_BUFFER_SIZE = 4096
|
|
};
|
|
};
|
|
enum {
|
|
enum {
|
|
@@ -263,35 +259,35 @@ query AudioFrames and ``get_stream_sampling_rate`` to query current mix rate.
|
|
MIX_FRAC_LEN = (1 << MIX_FRAC_BITS),
|
|
MIX_FRAC_LEN = (1 << MIX_FRAC_BITS),
|
|
MIX_FRAC_MASK = MIX_FRAC_LEN - 1,
|
|
MIX_FRAC_MASK = MIX_FRAC_LEN - 1,
|
|
};
|
|
};
|
|
- void * pcm_buffer;
|
|
|
|
|
|
+ void *pcm_buffer;
|
|
Ref<AudioStreamMyToneResampled> base;
|
|
Ref<AudioStreamMyToneResampled> base;
|
|
bool active;
|
|
bool active;
|
|
|
|
+
|
|
protected:
|
|
protected:
|
|
virtual void _mix_internal(AudioFrame *p_buffer, int p_frames);
|
|
virtual void _mix_internal(AudioFrame *p_buffer, int p_frames);
|
|
|
|
+
|
|
public:
|
|
public:
|
|
virtual void start(float p_from_pos = 0.0);
|
|
virtual void start(float p_from_pos = 0.0);
|
|
virtual void stop();
|
|
virtual void stop();
|
|
virtual bool is_playing() const;
|
|
virtual bool is_playing() const;
|
|
- virtual int get_loop_count() const; //times it looped
|
|
|
|
|
|
+ virtual int get_loop_count() const; // times it looped
|
|
virtual float get_playback_position() const;
|
|
virtual float get_playback_position() const;
|
|
virtual void seek(float p_time);
|
|
virtual void seek(float p_time);
|
|
- virtual float get_length() const; //if supported, otherwise return 0
|
|
|
|
|
|
+ virtual float get_length() const; // if supported, otherwise return 0
|
|
virtual float get_stream_sampling_rate();
|
|
virtual float get_stream_sampling_rate();
|
|
AudioStreamPlaybackResampledMyTone();
|
|
AudioStreamPlaybackResampledMyTone();
|
|
~AudioStreamPlaybackResampledMyTone();
|
|
~AudioStreamPlaybackResampledMyTone();
|
|
-
|
|
|
|
};
|
|
};
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
.. code:: cpp
|
|
.. code:: cpp
|
|
|
|
|
|
#include "mytone_audiostream_resampled.h"
|
|
#include "mytone_audiostream_resampled.h"
|
|
- #include "math/math_funcs.h"
|
|
|
|
- #include "print_string.h"
|
|
|
|
|
|
|
|
- AudioStreamPlaybackResampledMyTone::AudioStreamPlaybackResampledMyTone()
|
|
|
|
- : active(false){
|
|
|
|
|
|
+ #include "core/math/math_funcs.h"
|
|
|
|
+ #include "core/print_string.h"
|
|
|
|
+
|
|
|
|
+ AudioStreamPlaybackResampledMyTone::AudioStreamPlaybackResampledMyTone()
|
|
|
|
+ : active(false) {
|
|
AudioServer::get_singleton()->lock();
|
|
AudioServer::get_singleton()->lock();
|
|
pcm_buffer = AudioServer::get_singleton()->audio_data_alloc(PCM_BUFFER_SIZE);
|
|
pcm_buffer = AudioServer::get_singleton()->audio_data_alloc(PCM_BUFFER_SIZE);
|
|
zeromem(pcm_buffer, PCM_BUFFER_SIZE);
|
|
zeromem(pcm_buffer, PCM_BUFFER_SIZE);
|
|
@@ -303,37 +299,36 @@ query AudioFrames and ``get_stream_sampling_rate`` to query current mix rate.
|
|
pcm_buffer = NULL;
|
|
pcm_buffer = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- void AudioStreamPlaybackResampledMyTone::stop(){
|
|
|
|
|
|
+ void AudioStreamPlaybackResampledMyTone::stop() {
|
|
active = false;
|
|
active = false;
|
|
base->reset();
|
|
base->reset();
|
|
}
|
|
}
|
|
-
|
|
|
|
- void AudioStreamPlaybackResampledMyTone::start(float p_from_pos){
|
|
|
|
|
|
+ void AudioStreamPlaybackResampledMyTone::start(float p_from_pos) {
|
|
seek(p_from_pos);
|
|
seek(p_from_pos);
|
|
active = true;
|
|
active = true;
|
|
}
|
|
}
|
|
- void AudioStreamPlaybackResampledMyTone::seek(float p_time){
|
|
|
|
|
|
+ void AudioStreamPlaybackResampledMyTone::seek(float p_time) {
|
|
float max = get_length();
|
|
float max = get_length();
|
|
if (p_time < 0) {
|
|
if (p_time < 0) {
|
|
p_time = 0;
|
|
p_time = 0;
|
|
}
|
|
}
|
|
base->set_position(uint64_t(p_time * base->mix_rate) << MIX_FRAC_BITS);
|
|
base->set_position(uint64_t(p_time * base->mix_rate) << MIX_FRAC_BITS);
|
|
}
|
|
}
|
|
- void AudioStreamPlaybackResampledMyTone::_mix_internal(AudioFrame *p_buffer, int p_frames){
|
|
|
|
|
|
+ void AudioStreamPlaybackResampledMyTone::_mix_internal(AudioFrame *p_buffer, int p_frames) {
|
|
ERR_FAIL_COND(!active);
|
|
ERR_FAIL_COND(!active);
|
|
if (!active) {
|
|
if (!active) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
zeromem(pcm_buffer, PCM_BUFFER_SIZE);
|
|
zeromem(pcm_buffer, PCM_BUFFER_SIZE);
|
|
- int16_t * buf = (int16_t * )pcm_buffer;
|
|
|
|
|
|
+ int16_t *buf = (int16_t *)pcm_buffer;
|
|
base->gen_tone(buf, p_frames);
|
|
base->gen_tone(buf, p_frames);
|
|
|
|
|
|
- for(int i = 0; i < p_frames; i++){
|
|
|
|
- float sample = float(buf[i])/32767.0;
|
|
|
|
|
|
+ for(int i = 0; i < p_frames; i++) {
|
|
|
|
+ float sample = float(buf[i]) / 32767.0;
|
|
p_buffer[i] = AudioFrame(sample, sample);
|
|
p_buffer[i] = AudioFrame(sample, sample);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- float AudioStreamPlaybackResampledMyTone::get_stream_sampling_rate(){
|
|
|
|
|
|
+ float AudioStreamPlaybackResampledMyTone::get_stream_sampling_rate() {
|
|
return float(base->mix_rate);
|
|
return float(base->mix_rate);
|
|
}
|
|
}
|
|
int AudioStreamPlaybackResampledMyTone::get_loop_count() const {
|
|
int AudioStreamPlaybackResampledMyTone::get_loop_count() const {
|
|
@@ -349,13 +344,8 @@ query AudioFrames and ``get_stream_sampling_rate`` to query current mix rate.
|
|
return active;
|
|
return active;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
References:
|
|
References:
|
|
~~~~~~~~~~~
|
|
~~~~~~~~~~~
|
|
- `core/math/audio_frame.h <https://github.com/godotengine/godot/blob/master/core/math/audio_frame.h>`__
|
|
- `core/math/audio_frame.h <https://github.com/godotengine/godot/blob/master/core/math/audio_frame.h>`__
|
|
- `servers/audio/audio_stream.h <https://github.com/godotengine/godot/blob/master/servers/audio/audio_stream.h>`__
|
|
- `servers/audio/audio_stream.h <https://github.com/godotengine/godot/blob/master/servers/audio/audio_stream.h>`__
|
|
- `scene/audio/audioplayer.cpp <https://github.com/godotengine/godot/blob/master/scene/audio/audio_player.cpp>`__
|
|
- `scene/audio/audioplayer.cpp <https://github.com/godotengine/godot/blob/master/scene/audio/audio_player.cpp>`__
|
|
-
|
|
|
|
-
|
|
|