diff options
Diffstat (limited to 'servers')
-rw-r--r-- | servers/audio/audio_stream.cpp | 114 | ||||
-rw-r--r-- | servers/audio/audio_stream.h | 57 | ||||
-rw-r--r-- | servers/audio_server.cpp | 58 | ||||
-rw-r--r-- | servers/audio_server.h | 34 | ||||
-rw-r--r-- | servers/physics_2d/broad_phase_2d_sw.h | 2 | ||||
-rw-r--r-- | servers/register_server_types.cpp | 1 | ||||
-rw-r--r-- | servers/visual/shader_language.cpp | 67 | ||||
-rw-r--r-- | servers/visual_server.h | 2 |
8 files changed, 310 insertions, 25 deletions
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 113f23f8f2..eef8aba0c4 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "audio_stream.h" +#include "os/os.h" ////////////////////////////// @@ -99,6 +100,119 @@ void AudioStream::_bind_methods() { //////////////////////////////// +Ref<AudioStreamPlayback> AudioStreamMicrophone::instance_playback() { + Ref<AudioStreamPlaybackMicrophone> playback; + playback.instance(); + + playbacks.insert(playback.ptr()); + + playback->microphone = Ref<AudioStreamMicrophone>((AudioStreamMicrophone *)this); + playback->active = false; + + return playback; +} + +String AudioStreamMicrophone::get_stream_name() const { + + //if (audio_stream.is_valid()) { + //return "Random: " + audio_stream->get_name(); + //} + return "Microphone"; +} + +float AudioStreamMicrophone::get_length() const { + return 0; +} + +void AudioStreamMicrophone::_bind_methods() { +} + +AudioStreamMicrophone::AudioStreamMicrophone() { +} + +void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_frames) { + + AudioDriver::get_singleton()->lock(); + + Vector<int32_t> buf = AudioDriver::get_singleton()->get_input_buffer(); + unsigned int input_size = AudioDriver::get_singleton()->get_input_size(); + + // p_frames is multipled by two since an AudioFrame is stereo + if ((p_frames + MICROPHONE_PLAYBACK_DELAY * 2) > input_size) { + for (int i = 0; i < p_frames; i++) { + p_buffer[i] = AudioFrame(0.0f, 0.0f); + } + input_ofs = 0; + } else { + for (int i = 0; i < p_frames; i++) { + if (input_size >= input_ofs) { + float l = (buf[input_ofs++] >> 16) / 32768.f; + if (input_ofs >= buf.size()) { + input_ofs = 0; + } + float r = (buf[input_ofs++] >> 16) / 32768.f; + if (input_ofs >= buf.size()) { + input_ofs = 0; + } + + p_buffer[i] = AudioFrame(l, r); + } else { + p_buffer[i] = AudioFrame(0.0f, 0.0f); + } + } + } + + AudioDriver::get_singleton()->unlock(); +} + +void AudioStreamPlaybackMicrophone::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { + AudioStreamPlaybackResampled::mix(p_buffer, p_rate_scale, p_frames); +} + +float AudioStreamPlaybackMicrophone::get_stream_sampling_rate() { + return AudioDriver::get_singleton()->get_mix_rate(); +} + +void AudioStreamPlaybackMicrophone::start(float p_from_pos) { + input_ofs = 0; + + AudioDriver::get_singleton()->capture_start(); + + active = true; + _begin_resample(); +} + +void AudioStreamPlaybackMicrophone::stop() { + AudioDriver::get_singleton()->capture_stop(); + active = false; +} + +bool AudioStreamPlaybackMicrophone::is_playing() const { + return active; +} + +int AudioStreamPlaybackMicrophone::get_loop_count() const { + return 0; +} + +float AudioStreamPlaybackMicrophone::get_playback_position() const { + return 0; +} + +void AudioStreamPlaybackMicrophone::seek(float p_time) { + return; // Can't seek a microphone input +} + +AudioStreamPlaybackMicrophone::~AudioStreamPlaybackMicrophone() { + microphone->playbacks.erase(this); + stop(); +} + +AudioStreamPlaybackMicrophone::AudioStreamPlaybackMicrophone() { +} + +//////////////////////////////// + void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_stream) { audio_stream = p_audio_stream; diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index 3312ce1ff6..66e1b6ee2f 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -94,6 +94,63 @@ public: virtual float get_length() const = 0; //if supported, otherwise return 0 }; +// Microphone + +class AudioStreamPlaybackMicrophone; + +class AudioStreamMicrophone : public AudioStream { + + GDCLASS(AudioStreamMicrophone, AudioStream) + friend class AudioStreamPlaybackMicrophone; + + Set<AudioStreamPlaybackMicrophone *> playbacks; + +protected: + static void _bind_methods(); + +public: + virtual Ref<AudioStreamPlayback> instance_playback(); + virtual String get_stream_name() const; + + virtual float get_length() const; //if supported, otherwise return 0 + + AudioStreamMicrophone(); +}; + +class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled { + + GDCLASS(AudioStreamPlaybackMicrophone, AudioStreamPlayback) + friend class AudioStreamMicrophone; + + const int MICROPHONE_PLAYBACK_DELAY = 256; + + bool active; + unsigned int input_ofs; + + Ref<AudioStreamMicrophone> microphone; + +protected: + virtual void _mix_internal(AudioFrame *p_buffer, int p_frames); + virtual float get_stream_sampling_rate(); + +public: + virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames); + + virtual void start(float p_from_pos = 0.0); + virtual void stop(); + virtual bool is_playing() const; + + virtual int get_loop_count() const; //times it looped + + virtual float get_playback_position() const; + virtual void seek(float p_time); + + ~AudioStreamPlaybackMicrophone(); + AudioStreamPlaybackMicrophone(); +}; + +// + class AudioStreamPlaybackRandomPitch; class AudioStreamRandomPitch : public AudioStream { diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 2eaa2ce8e7..f3934e5c01 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -33,6 +33,7 @@ #include "os/file_access.h" #include "os/os.h" #include "project_settings.h" +#include "scene/resources/audio_stream_sample.h" #include "servers/audio/audio_driver_dummy.h" #include "servers/audio/effects/audio_effect_compressor.h" #ifdef TOOLS_ENABLED @@ -79,6 +80,17 @@ double AudioDriver::get_mix_time() const { return total; } +void AudioDriver::input_buffer_write(int32_t sample) { + + input_buffer.write[input_position++] = sample; + if (input_position >= input_buffer.size()) { + input_position = 0; + } + if (input_size < input_buffer.size()) { + input_size++; + } +} + AudioDriver::SpeakerMode AudioDriver::get_speaker_mode_by_total_channels(int p_channels) const { switch (p_channels) { case 4: return SPEAKER_SURROUND_31; @@ -113,6 +125,14 @@ String AudioDriver::get_device() { return "Default"; } +Array AudioDriver::capture_get_device_list() { + Array list; + + list.push_back("Default"); + + return list; +} + AudioDriver::AudioDriver() { _last_mix_time = 0; @@ -123,14 +143,19 @@ AudioDriver::AudioDriver() { #endif } -AudioDriver *AudioDriverManager::drivers[MAX_DRIVERS]; -int AudioDriverManager::driver_count = 0; AudioDriverDummy AudioDriverManager::dummy_driver; +AudioDriver *AudioDriverManager::drivers[MAX_DRIVERS] = { + &AudioDriverManager::dummy_driver, +}; +int AudioDriverManager::driver_count = 1; void AudioDriverManager::add_driver(AudioDriver *p_driver) { ERR_FAIL_COND(driver_count >= MAX_DRIVERS); - drivers[driver_count++] = p_driver; + drivers[driver_count - 1] = p_driver; + + // Last driver is always our dummy driver + drivers[driver_count++] = &AudioDriverManager::dummy_driver; } int AudioDriverManager::get_driver_count() { @@ -163,14 +188,6 @@ void AudioDriverManager::initialize(int p_driver) { return; } } - - // Fallback to our dummy driver - if (dummy_driver.init() == OK) { - ERR_PRINT("AudioDriverManager: all drivers failed, falling back to dummy driver"); - dummy_driver.set_singleton(); - } else { - ERR_PRINT("AudioDriverManager: dummy driver failed to init()"); - } } AudioDriver *AudioDriverManager::get_driver(int p_driver) { @@ -1201,6 +1218,21 @@ void AudioServer::set_device(String device) { AudioDriver::get_singleton()->set_device(device); } +Array AudioServer::capture_get_device_list() { + + return AudioDriver::get_singleton()->capture_get_device_list(); +} + +String AudioServer::capture_get_device() { + + return AudioDriver::get_singleton()->capture_get_device(); +} + +void AudioServer::capture_set_device(const String &p_name) { + + AudioDriver::get_singleton()->capture_set_device(p_name); +} + void AudioServer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bus_count", "amount"), &AudioServer::set_bus_count); @@ -1251,6 +1283,10 @@ void AudioServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_device"), &AudioServer::get_device); ClassDB::bind_method(D_METHOD("set_device"), &AudioServer::set_device); + ClassDB::bind_method(D_METHOD("capture_get_device_list"), &AudioServer::capture_get_device_list); + ClassDB::bind_method(D_METHOD("capture_get_device"), &AudioServer::capture_get_device); + ClassDB::bind_method(D_METHOD("capture_set_device"), &AudioServer::capture_set_device); + ClassDB::bind_method(D_METHOD("set_bus_layout", "bus_layout"), &AudioServer::set_bus_layout); ClassDB::bind_method(D_METHOD("generate_bus_layout"), &AudioServer::generate_bus_layout); diff --git a/servers/audio_server.h b/servers/audio_server.h index 258fd1d9b0..2663a0f968 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -38,6 +38,8 @@ #include "variant.h" class AudioDriverDummy; +class AudioStream; +class AudioStreamSample; class AudioDriver { @@ -51,8 +53,13 @@ class AudioDriver { #endif protected: + Vector<int32_t> input_buffer; + unsigned int input_position; + unsigned int input_size; + void audio_server_process(int p_frames, int32_t *p_buffer, bool p_update_mix_time = true); void update_mix_time(int p_frames); + void input_buffer_write(int32_t sample); #ifdef DEBUG_ENABLED _FORCE_INLINE_ void start_counting_ticks() { prof_ticks = OS::get_singleton()->get_ticks_usec(); } @@ -91,11 +98,21 @@ public: virtual void unlock() = 0; virtual void finish() = 0; + virtual Error capture_start() { return FAILED; } + virtual Error capture_stop() { return FAILED; } + virtual void capture_set_device(const String &p_name) {} + virtual String capture_get_device() { return "Default"; } + virtual Array capture_get_device_list(); // TODO: convert this and get_device_list to PoolStringArray + virtual float get_latency() { return 0; } SpeakerMode get_speaker_mode_by_total_channels(int p_channels) const; int get_total_channels_by_speaker_mode(SpeakerMode) const; + Vector<int32_t> get_input_buffer() { return input_buffer; } + unsigned int get_input_position() { return input_position; } + unsigned int get_input_size() { return input_size; } + #ifdef DEBUG_ENABLED uint64_t get_profiling_time() const { return prof_time; } void reset_profiling_time() { prof_time = 0; } @@ -222,6 +239,18 @@ private: void _mix_step(); +#if 0 + struct AudioInBlock { + + Ref<AudioStreamSample> audio_stream; + int current_position; + bool loops; + }; + + Map<StringName, AudioInBlock *> audio_in_block_map; + Vector<AudioInBlock *> audio_in_blocks; +#endif + struct CallbackItem { AudioCallback callback; @@ -335,8 +364,11 @@ public: String get_device(); void set_device(String device); - float get_output_latency() { return output_latency; } + Array capture_get_device_list(); + String capture_get_device(); + void capture_set_device(const String &p_name); + float get_output_latency() { return output_latency; } AudioServer(); virtual ~AudioServer(); }; diff --git a/servers/physics_2d/broad_phase_2d_sw.h b/servers/physics_2d/broad_phase_2d_sw.h index 80ae970624..d7d236c4c6 100644 --- a/servers/physics_2d/broad_phase_2d_sw.h +++ b/servers/physics_2d/broad_phase_2d_sw.h @@ -31,8 +31,8 @@ #ifndef BROAD_PHASE_2D_SW_H #define BROAD_PHASE_2D_SW_H -#include "math_2d.h" #include "math_funcs.h" +#include "rect2.h" class CollisionObject2DSW; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 156e8c8bea..4c764641e3 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -104,6 +104,7 @@ void register_server_types() { ClassDB::register_virtual_class<AudioStream>(); ClassDB::register_virtual_class<AudioStreamPlayback>(); + ClassDB::register_class<AudioStreamMicrophone>(); ClassDB::register_class<AudioStreamRandomPitch>(); ClassDB::register_virtual_class<AudioEffect>(); ClassDB::register_class<AudioEffectEQ>(); diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index eb0784c6b4..ca50d0d049 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -528,13 +528,14 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { bool hexa_found = false; bool sign_found = false; bool minus_exponent_found = false; + bool float_suffix_found = false; String str; int i = 0; while (true) { if (GETCHAR(i) == '.') { - if (period_found || exponent_found) + if (period_found || exponent_found || hexa_found || float_suffix_found) return _make_token(TK_ERROR, "Invalid numeric constant"); period_found = true; } else if (GETCHAR(i) == 'x') { @@ -542,11 +543,16 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_ERROR, "Invalid numeric constant"); hexa_found = true; } else if (GETCHAR(i) == 'e') { - if (hexa_found || exponent_found) + if (hexa_found || exponent_found || float_suffix_found) return _make_token(TK_ERROR, "Invalid numeric constant"); exponent_found = true; + } else if (GETCHAR(i) == 'f') { + if (hexa_found || exponent_found) + return _make_token(TK_ERROR, "Invalid numeric constant"); + float_suffix_found = true; } else if (_is_number(GETCHAR(i))) { - //all ok + if (float_suffix_found) + return _make_token(TK_ERROR, "Invalid numeric constant"); } else if (hexa_found && _is_hex(GETCHAR(i))) { } else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) { @@ -562,21 +568,60 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { i++; } - if (!_is_number(str[str.length() - 1])) - return _make_token(TK_ERROR, "Invalid numeric constant"); + CharType last_char = str[str.length() - 1]; + + if (hexa_found) { + //hex integers eg."0xFF" or "0x12AB", etc - NOT supported yet + return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant - Not supported"); + } else if (period_found || float_suffix_found) { + //floats + if (period_found) { + if (float_suffix_found) { + //checks for eg "1.f" or "1.99f" notations + if (last_char != 'f') { + return _make_token(TK_ERROR, "Invalid (float) numeric constant"); + } + } else { + //checks for eg. "1." or "1.99" notations + if (last_char != '.' && !_is_number(last_char)) { + return _make_token(TK_ERROR, "Invalid (float) numeric constant"); + } + } + } else if (float_suffix_found) { + // if no period found the float suffix must be the last character, like in "2f" for "2.0" + if (last_char != 'f') { + return _make_token(TK_ERROR, "Invalid (float) numeric constant"); + } + } + + if (float_suffix_found) { + //strip the suffix + str = str.left(str.length() - 1); + //compensate reading cursor position + char_idx += 1; + } + + if (!str.is_valid_float()) { + return _make_token(TK_ERROR, "Invalid (float) numeric constant"); + } + } else { + //integers + if (!_is_number(last_char)) { + return _make_token(TK_ERROR, "Invalid (integer) numeric constant"); + } + if (!str.is_valid_integer()) { + return _make_token(TK_ERROR, "Invalid numeric constant"); + } + } char_idx += str.length(); Token tk; - if (period_found || minus_exponent_found) + if (period_found || minus_exponent_found || float_suffix_found) tk.type = TK_REAL_CONSTANT; else tk.type = TK_INT_CONSTANT; - if (!str.is_valid_float()) { - return _make_token(TK_ERROR, "Invalid numeric constant"); - } - - tk.constant = str.to_double(); + tk.constant = str.to_double(); //wont work with hex tk.line = tk_line; return tk; diff --git a/servers/visual_server.h b/servers/visual_server.h index 0ec902c18c..fd7f96339e 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -34,9 +34,9 @@ #include "bsp_tree.h" #include "geometry.h" #include "image.h" -#include "math_2d.h" #include "object.h" #include "rid.h" +#include "transform_2d.h" #include "variant.h" /** |