diff options
Diffstat (limited to '')
| -rw-r--r-- | scene/audio/SCsub | 7 | ||||
| -rw-r--r-- | scene/audio/event_player.cpp | 356 | ||||
| -rw-r--r-- | scene/audio/event_player.h | 109 | ||||
| -rw-r--r-- | scene/audio/sample_player.cpp | 707 | ||||
| -rw-r--r-- | scene/audio/sample_player.h | 198 | ||||
| -rw-r--r-- | scene/audio/sound_room_params.cpp | 180 | ||||
| -rw-r--r-- | scene/audio/sound_room_params.h | 100 | ||||
| -rw-r--r-- | scene/audio/stream_player.cpp | 290 | ||||
| -rw-r--r-- | scene/audio/stream_player.h | 89 |
9 files changed, 2036 insertions, 0 deletions
diff --git a/scene/audio/SCsub b/scene/audio/SCsub new file mode 100644 index 000000000..055d2f247 --- /dev/null +++ b/scene/audio/SCsub @@ -0,0 +1,7 @@ +Import('env') + +env.add_source_files(env.scene_sources,"*.cpp") + +Export('env') + + diff --git a/scene/audio/event_player.cpp b/scene/audio/event_player.cpp new file mode 100644 index 000000000..07162e42f --- /dev/null +++ b/scene/audio/event_player.cpp @@ -0,0 +1,356 @@ +/*************************************************************************/ +/* event_player.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "event_player.h" + + +void EventPlayer::_notification(int p_what) { + + switch(p_what) { + + case NOTIFICATION_ENTER_SCENE: { + + //set_idle_process(false); //don't annoy + if (playback.is_valid() && autoplay && !get_scene()->is_editor_hint()) + play(); + } break; + case NOTIFICATION_EXIT_SCENE: { + + stop(); //wathever it may be doing, stop + } break; + } +} + + + +void EventPlayer::set_stream(const Ref<EventStream> &p_stream) { + + stop(); + stream=p_stream; + if (stream.is_valid()) + playback=stream->instance_playback(); + + if (playback.is_valid()) { + + playback->set_loop(loops); + playback->set_paused(paused); + playback->set_volume(volume); + for(int i=0;i<(MIN(MAX_CHANNELS,stream->get_channel_count()));i++) + playback->set_channel_volume(i,channel_volume[i]); + } + + +} + +Ref<EventStream> EventPlayer::get_stream() const { + + return stream; +} + + +void EventPlayer::play() { + + ERR_FAIL_COND(!is_inside_scene()); + if (playback.is_null()) + return; + if (playback->is_playing()) { + AudioServer::get_singleton()->lock(); + stop(); + AudioServer::get_singleton()->unlock(); + } + + AudioServer::get_singleton()->lock(); + playback->play(); + AudioServer::get_singleton()->unlock(); + +} + +void EventPlayer::stop() { + + if (!is_inside_scene()) + return; + if (playback.is_null()) + return; + + AudioServer::get_singleton()->lock(); + playback->stop(); + AudioServer::get_singleton()->unlock(); +} + +bool EventPlayer::is_playing() const { + + if (playback.is_null()) + return false; + + return playback->is_playing(); +} + +void EventPlayer::set_loop(bool p_enable) { + + loops=p_enable; + if (playback.is_null()) + return; + playback->set_loop(loops); + +} +bool EventPlayer::has_loop() const { + + return loops; +} + +void EventPlayer::set_volume(float p_volume) { + + volume=p_volume; + if (playback.is_valid()) + playback->set_volume(volume); +} + +float EventPlayer::get_volume() const { + + return volume; +} + + +void EventPlayer::set_volume_db(float p_db) { + + if (p_db<-79) + set_volume(0); + else + set_volume(Math::db2linear(p_db)); +} + +float EventPlayer::get_volume_db() const { + + if (volume==0) + return -80; + else + return Math::linear2db(volume); +} + +void EventPlayer::set_pitch_scale(float p_pitch_scale) { + + pitch_scale=p_pitch_scale; + if (playback.is_valid()) + playback->set_pitch_scale(pitch_scale); +} + +float EventPlayer::get_pitch_scale() const { + + return pitch_scale; +} + +void EventPlayer::set_tempo_scale(float p_tempo_scale) { + + tempo_scale=p_tempo_scale; + if (playback.is_valid()) + playback->set_tempo_scale(tempo_scale); +} + +float EventPlayer::get_tempo_scale() const { + + return tempo_scale; +} + + +String EventPlayer::get_stream_name() const { + + if (stream.is_null()) + return "<No Stream>"; + return stream->get_name(); + +} + +int EventPlayer::get_loop_count() const { + + if (playback.is_null()) + return 0; + return playback->get_loop_count(); + +} + +float EventPlayer::get_pos() const { + + if (playback.is_null()) + return 0; + return playback->get_pos(); + +} + +float EventPlayer::get_length() const { + + if (stream.is_null()) + return 0; + return stream->get_length(); +} +void EventPlayer::seek_pos(float p_time) { + + if (playback.is_null()) + return; + return playback->seek_pos(p_time); + +} + +void EventPlayer::set_autoplay(bool p_enable) { + + autoplay=p_enable; +} + +bool EventPlayer::has_autoplay() const { + + return autoplay; +} + +void EventPlayer::set_paused(bool p_paused) { + + paused=p_paused; + if (playback.is_valid()) + playback->set_paused(p_paused); +} + +bool EventPlayer::is_paused() const { + + return paused; +} + +void EventPlayer::_set_play(bool p_play) { + + _play=p_play; + if (is_inside_scene()) { + if(_play) + play(); + else + stop(); + } + +} + +bool EventPlayer::_get_play() const{ + + return _play; +} + +void EventPlayer::set_channel_volume(int p_channel,float p_volume) { + + ERR_FAIL_INDEX(p_channel,MAX_CHANNELS); + channel_volume[p_channel]=p_volume; + if (playback.is_valid()) + playback->set_channel_volume(p_channel,p_volume); +} + +float EventPlayer::get_channel_volume(int p_channel) const{ + + ERR_FAIL_INDEX_V(p_channel,MAX_CHANNELS,0); + return channel_volume[p_channel]; + +} + +float EventPlayer::get_channel_last_note_time(int p_channel) const { + + if (playback.is_valid()) + return playback->get_last_note_time(p_channel); + + return 0; +} + +void EventPlayer::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_stream","stream:Stream"),&EventPlayer::set_stream); + ObjectTypeDB::bind_method(_MD("get_stream:Stream"),&EventPlayer::get_stream); + + ObjectTypeDB::bind_method(_MD("play"),&EventPlayer::play); + ObjectTypeDB::bind_method(_MD("stop"),&EventPlayer::stop); + + ObjectTypeDB::bind_method(_MD("is_playing"),&EventPlayer::is_playing); + + ObjectTypeDB::bind_method(_MD("set_paused","paused"),&EventPlayer::set_paused); + ObjectTypeDB::bind_method(_MD("is_paused"),&EventPlayer::is_paused); + + ObjectTypeDB::bind_method(_MD("set_loop","enabled"),&EventPlayer::set_loop); + ObjectTypeDB::bind_method(_MD("has_loop"),&EventPlayer::has_loop); + + ObjectTypeDB::bind_method(_MD("set_volume","volume"),&EventPlayer::set_volume); + ObjectTypeDB::bind_method(_MD("get_volume"),&EventPlayer::get_volume); + + ObjectTypeDB::bind_method(_MD("set_pitch_scale","pitch_scale"),&EventPlayer::set_pitch_scale); + ObjectTypeDB::bind_method(_MD("get_pitch_scale"),&EventPlayer::get_pitch_scale); + + ObjectTypeDB::bind_method(_MD("set_tempo_scale","tempo_scale"),&EventPlayer::set_tempo_scale); + ObjectTypeDB::bind_method(_MD("get_tempo_scale"),&EventPlayer::get_tempo_scale); + + ObjectTypeDB::bind_method(_MD("set_volume_db","db"),&EventPlayer::set_volume_db); + ObjectTypeDB::bind_method(_MD("get_volume_db"),&EventPlayer::get_volume_db); + + ObjectTypeDB::bind_method(_MD("get_stream_name"),&EventPlayer::get_stream_name); + ObjectTypeDB::bind_method(_MD("get_loop_count"),&EventPlayer::get_loop_count); + + ObjectTypeDB::bind_method(_MD("get_pos"),&EventPlayer::get_pos); + ObjectTypeDB::bind_method(_MD("seek_pos","time"),&EventPlayer::seek_pos); + + ObjectTypeDB::bind_method(_MD("set_autoplay","enabled"),&EventPlayer::set_autoplay); + ObjectTypeDB::bind_method(_MD("has_autoplay"),&EventPlayer::has_autoplay); + + ObjectTypeDB::bind_method(_MD("set_channel_volume","idx","channel_volume"),&EventPlayer::set_channel_volume); + ObjectTypeDB::bind_method(_MD("get_channel_volume""idx"),&EventPlayer::get_channel_volume); + + ObjectTypeDB::bind_method(_MD("get_length"),&EventPlayer::get_length); + + + ObjectTypeDB::bind_method(_MD("get_channel_last_note_time"),&EventPlayer::get_channel_last_note_time); + + ObjectTypeDB::bind_method(_MD("_set_play","play"),&EventPlayer::_set_play); + ObjectTypeDB::bind_method(_MD("_get_play"),&EventPlayer::_get_play); + + ADD_PROPERTY( PropertyInfo(Variant::OBJECT, "stream/stream", PROPERTY_HINT_RESOURCE_TYPE,"EventStream"), _SCS("set_stream"), _SCS("get_stream") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/play"), _SCS("_set_play"), _SCS("_get_play") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/loop"), _SCS("set_loop"), _SCS("has_loop") ); + ADD_PROPERTY( PropertyInfo(Variant::REAL, "stream/volume_db", PROPERTY_HINT_RANGE,"-80,24,0.01"), _SCS("set_volume_db"), _SCS("get_volume_db") ); + ADD_PROPERTY( PropertyInfo(Variant::REAL, "stream/pitch_scale", PROPERTY_HINT_RANGE,"0.001,16,0.001"), _SCS("set_pitch_scale"), _SCS("get_pitch_scale") ); + ADD_PROPERTY( PropertyInfo(Variant::REAL, "stream/tempo_scale", PROPERTY_HINT_RANGE,"0.001,16,0.001"), _SCS("set_tempo_scale"), _SCS("get_tempo_scale") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/autoplay"), _SCS("set_autoplay"), _SCS("has_autoplay") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/paused"), _SCS("set_paused"), _SCS("is_paused") ); +} + + +EventPlayer::EventPlayer() { + + volume=1; + loops=false; + paused=false; + autoplay=false; + _play=false; + pitch_scale=1.0; + tempo_scale=1.0; + for(int i=0;i<MAX_CHANNELS;i++) + channel_volume[i]=1.0; + +} + +EventPlayer::~EventPlayer() { + + +} diff --git a/scene/audio/event_player.h b/scene/audio/event_player.h new file mode 100644 index 000000000..2b3111b36 --- /dev/null +++ b/scene/audio/event_player.h @@ -0,0 +1,109 @@ +/*************************************************************************/ +/* event_player.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef EVENT_PLAYER_H +#define EVENT_PLAYER_H + + +#include "scene/main/node.h" +#include "scene/resources/event_stream.h" +class EventPlayer : public Node { + + OBJ_TYPE(EventPlayer,Node); + + + enum { + MAX_CHANNELS=256 + }; + + Ref<EventStreamPlayback> playback; + Ref<EventStream> stream; + bool paused; + bool autoplay; + bool loops; + float volume; + + float tempo_scale; + float pitch_scale; + + float channel_volume[MAX_CHANNELS]; + bool _play; + void _set_play(bool p_play); + bool _get_play() const; +protected: + void _notification(int p_what); + + static void _bind_methods(); + +public: + + void set_stream(const Ref<EventStream> &p_stream); + Ref<EventStream> get_stream() const; + + void play(); + void stop(); + bool is_playing() const; + + void set_paused(bool p_paused); + bool is_paused() const; + + void set_loop(bool p_enable); + bool has_loop() const; + + void set_volume(float p_vol); + float get_volume() const; + + void set_volume_db(float p_db); + float get_volume_db() const; + + void set_pitch_scale(float p_scale); + float get_pitch_scale() const; + + void set_tempo_scale(float p_scale); + float get_tempo_scale() const; + + String get_stream_name() const; + + int get_loop_count() const; + + float get_pos() const; + void seek_pos(float p_time); + float get_length() const; + void set_autoplay(bool p_vol); + bool has_autoplay() const; + + void set_channel_volume(int p_channel,float p_volume); + float get_channel_volume(int p_channel) const; + + float get_channel_last_note_time(int p_channel) const; + + EventPlayer(); + ~EventPlayer(); +}; + +#endif // EVENT_PLAYER_H diff --git a/scene/audio/sample_player.cpp b/scene/audio/sample_player.cpp new file mode 100644 index 000000000..be53b8243 --- /dev/null +++ b/scene/audio/sample_player.cpp @@ -0,0 +1,707 @@ +/*************************************************************************/ +/* sample_player.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "sample_player.h" + +#include "servers/audio_server.h" + + +bool SamplePlayer::_set(const StringName& p_name, const Variant& p_value) { + + String name=p_name; + + if (name=="play/play") { + if (library.is_valid()) { + + String what=p_value; + if (what=="") + stop_all(); + else + play(what); + + played_back=what; + } + } else if (name=="config/samples") + set_sample_library(p_value); + else if (name=="config/voices") + set_voice_count(p_value); + else if (name.begins_with("default/")) { + + String what=name.right(7); + + if (what=="volume_db") + set_default_volume_db(p_value); + else if (what=="pitch_scale") + set_default_pitch_scale(p_value); + else if (what=="pan") + _default.pan=p_value; + else if (what=="depth") + _default.depth=p_value; + else if (what=="height") + _default.height=p_value; + else if (what=="filter/type") + _default.filter_type=FilterType(p_value.operator int()); + else if (what=="filter/cutoff") + _default.filter_cutoff=p_value; + else if (what=="filter/resonance") + _default.filter_resonance=p_value; + else if (what=="filter/gain") + _default.filter_gain=p_value; + else if (what=="reverb_room") + _default.reverb_room=ReverbRoomType(p_value.operator int()); + else if (what=="reverb_send") + _default.reverb_send=p_value; + else if (what=="chorus_send") + _default.chorus_send=p_value; + else + return false; + + + } else + return false; + + return true; +} + +bool SamplePlayer::_get(const StringName& p_name,Variant &r_ret) const { + + + String name=p_name; + + if (name=="play/play") { + r_ret=played_back; + } else if (name=="config/voices") { + r_ret= get_voice_count(); + } else if (name=="config/samples") { + + r_ret= get_sample_library(); + } else if (name.begins_with("default/")) { + + String what=name.get_slice("/",1); + + if (what=="volume_db") + r_ret= get_default_volume_db(); + else if (what=="pitch_scale") + r_ret= get_default_pitch_scale(); + else if (what=="pan") + r_ret= _default.pan; + else if (what=="depth") + r_ret= _default.depth; + else if (what=="height") + r_ret= _default.height; + else if (what=="filter/type") + r_ret= _default.filter_type; + else if (what=="filter/cutoff") + r_ret= _default.filter_cutoff; + else if (what=="filter/resonance") + r_ret= _default.filter_resonance; + else if (what=="filter/gain") + r_ret= _default.filter_gain; + else if (what=="reverb_room") + r_ret= _default.reverb_room; + else if (what=="reverb_send") + r_ret= _default.reverb_send; + else if (what=="chorus_send") + r_ret= _default.chorus_send; + else + return false; + + + } else + return false; + + return true; +} + +void SamplePlayer::_get_property_list(List<PropertyInfo> *p_list) const { + + String en=""; + if (library.is_valid()) { + List<StringName> samples; + Ref<SampleLibrary> ncl=library; + ncl->get_sample_list(&samples); + for (List<StringName>::Element *E=samples.front();E;E=E->next()) { + + en+=","; + en+=E->get(); + } + } + + p_list->push_back( PropertyInfo( Variant::STRING, "play/play", PROPERTY_HINT_ENUM, en,PROPERTY_USAGE_EDITOR)); + p_list->push_back( PropertyInfo( Variant::INT, "config/voices", PROPERTY_HINT_RANGE, "1,256,1")); + p_list->push_back( PropertyInfo( Variant::OBJECT, "config/samples", PROPERTY_HINT_RESOURCE_TYPE, "SampleLibrary")); + p_list->push_back( PropertyInfo( Variant::REAL, "default/volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01")); + p_list->push_back( PropertyInfo( Variant::REAL, "default/pitch_scale", PROPERTY_HINT_RANGE, "0.01,48,0.01")); + p_list->push_back( PropertyInfo( Variant::REAL, "default/pan", PROPERTY_HINT_RANGE, "-1,1,0.01")); + p_list->push_back( PropertyInfo( Variant::REAL, "default/depth", PROPERTY_HINT_RANGE, "-1,1,0.01")); + p_list->push_back( PropertyInfo( Variant::REAL, "default/height", PROPERTY_HINT_RANGE, "-1,1,0.01")); + p_list->push_back( PropertyInfo( Variant::INT, "default/filter/type", PROPERTY_HINT_ENUM, "Disabled,Lowpass,Bandpass,Highpass,Notch,Peak,BandLimit,LowShelf,HighShelf")); + p_list->push_back( PropertyInfo( Variant::REAL, "default/filter/cutoff", PROPERTY_HINT_RANGE, "20,16384.0,0.01")); + p_list->push_back( PropertyInfo( Variant::REAL, "default/filter/resonance", PROPERTY_HINT_RANGE, "0,4,0.01")); + p_list->push_back( PropertyInfo( Variant::REAL, "default/filter/gain", PROPERTY_HINT_RANGE, "0,2,0.01")); + p_list->push_back( PropertyInfo( Variant::INT, "default/reverb_room", PROPERTY_HINT_ENUM, "Small,Medimum,Large,Hall")); + p_list->push_back( PropertyInfo( Variant::REAL, "default/reverb_send", PROPERTY_HINT_RANGE, "0,1,0.01")); + p_list->push_back( PropertyInfo( Variant::REAL, "default/chorus_send", PROPERTY_HINT_RANGE, "0,1,0.01")); + + +} + + +SamplePlayer::Voice::Voice() { + + voice=AudioServer::get_singleton()->voice_create(); + clear(); +} + + +void SamplePlayer::Voice::clear() { + + check=0; + + mix_rate=44100; + volume=1; + pan=0; + pan_depth=0; + pan_height=0; + filter_type=FILTER_NONE; + filter_cutoff=0; + filter_resonance=0; + chorus_send=0; + reverb_room=REVERB_HALL; + reverb_send=0; + active=false; + +} +SamplePlayer::Voice::~Voice() { + + AudioServer::get_singleton()->free(voice); +} + + +void SamplePlayer::set_voice_count(int p_voice_count) { + + ERR_FAIL_COND( p_voice_count <1 || p_voice_count >0xFFFE ); + + voices.resize(p_voice_count); +} + +int SamplePlayer::get_voice_count() const { + + return voices.size(); +} + +SamplePlayer::VoiceID SamplePlayer::play(const String& p_name,bool unique) { + + if (library.is_null()) + return INVALID_VOICE_ID; + ERR_FAIL_COND_V( !library->has_sample(p_name), INVALID_VOICE_ID ); + + Ref<Sample> sample = library->get_sample(p_name); + float vol_change = library->sample_get_volume_db(p_name); + float pitch_change = library->sample_get_pitch_scale(p_name); + + last_check++; + last_id = (last_id + 1) % voices.size(); + + Voice&v = voices[last_id]; + v.clear(); + + + v.mix_rate=sample->get_mix_rate()*(_default.pitch_scale*pitch_change); + v.sample_mix_rate=sample->get_mix_rate(); + v.check=last_check; + v.volume=Math::db2linear(_default.volume_db+vol_change); + v.pan=_default.pan; + v.pan_depth=_default.depth; + v.pan_height=_default.height; + v.filter_type=_default.filter_type; + v.filter_cutoff=_default.filter_cutoff; + v.filter_resonance=_default.filter_resonance; + v.filter_gain=_default.filter_gain; + v.chorus_send=_default.chorus_send; + v.reverb_room=_default.reverb_room; + v.reverb_send=_default.reverb_send; + + AudioServer::get_singleton()->voice_play(v.voice,sample->get_rid()); + AudioServer::get_singleton()->voice_set_mix_rate(v.voice,v.mix_rate); + AudioServer::get_singleton()->voice_set_volume(v.voice,v.volume); + AudioServer::get_singleton()->voice_set_pan(v.voice,v.pan,v.pan_depth,v.pan_height); + AudioServer::get_singleton()->voice_set_filter(v.voice,(AudioServer::FilterType)v.filter_type,v.filter_cutoff,v.filter_resonance,v.filter_gain); + AudioServer::get_singleton()->voice_set_chorus(v.voice,v.chorus_send); + AudioServer::get_singleton()->voice_set_reverb(v.voice,(AudioServer::ReverbRoomType)v.reverb_room,v.reverb_send); + + v.active=true; + + if (unique) { + + for(int i=0;i<voices.size();i++) { + + if (!voices[i].active || uint32_t(i)==last_id) + continue; + + AudioServer::get_singleton()->voice_stop(voices[i].voice); + + voices[i].clear(); + } + + } + + return last_id | (last_check<<16); +} + +void SamplePlayer::stop_all() { + + + for(int i=0;i<voices.size();i++) { + + if (!voices[i].active) + continue; + + AudioServer::get_singleton()->voice_stop(voices[i].voice); + voices[i].clear(); + } + +} + +#define _GET_VOICE\ + uint32_t voice=p_voice&0xFFFF;\ + ERR_FAIL_COND(voice > (uint32_t)voices.size());\ + Voice &v=voices[voice];\ + if (v.check!=uint32_t(p_voice>>16))\ + return;\ + ERR_FAIL_COND(!v.active); + +void SamplePlayer::stop(VoiceID p_voice) { + + _GET_VOICE + + AudioServer::get_singleton()->voice_stop(v.voice); + v.active=false; + +} + +void SamplePlayer::set_mix_rate(VoiceID p_voice, int p_mix_rate) { + + _GET_VOICE + + v.mix_rate=p_mix_rate; + AudioServer::get_singleton()->voice_set_mix_rate(v.voice,v.mix_rate); + +} +void SamplePlayer::set_pitch_scale(VoiceID p_voice, float p_pitch_scale) { + + _GET_VOICE + + v.mix_rate=v.sample_mix_rate*p_pitch_scale; + AudioServer::get_singleton()->voice_set_mix_rate(v.voice,v.mix_rate); + +} +void SamplePlayer::set_volume(VoiceID p_voice, float p_volume) { + + + _GET_VOICE + v.volume=p_volume; + AudioServer::get_singleton()->voice_set_volume(v.voice,v.volume); + +} + +void SamplePlayer::set_volume_db(VoiceID p_voice, float p_db) { + + //@TODO handle 0 volume as -80db or something + _GET_VOICE + v.volume=Math::db2linear(p_db); + AudioServer::get_singleton()->voice_set_volume(v.voice,v.volume); + +} + +void SamplePlayer::set_pan(VoiceID p_voice, float p_pan,float p_pan_depth,float p_pan_height) { + + _GET_VOICE + v.pan=p_pan; + v.pan_depth=p_pan_depth; + v.pan_height=p_pan_height; + + AudioServer::get_singleton()->voice_set_pan(v.voice,v.pan,v.pan_depth,v.pan_height); + +} + +void SamplePlayer::set_filter(VoiceID p_voice,FilterType p_filter,float p_cutoff,float p_resonance,float p_gain) { + + _GET_VOICE + v.filter_type=p_filter; + v.filter_cutoff=p_cutoff; + v.filter_resonance=p_resonance; + v.filter_gain=p_gain; + + AudioServer::get_singleton()->voice_set_filter(v.voice,(AudioServer::FilterType)p_filter,p_cutoff,p_resonance); + +} +void SamplePlayer::set_chorus(VoiceID p_voice,float p_send) { + + _GET_VOICE + v.chorus_send=p_send; + + AudioServer::get_singleton()->voice_set_chorus(v.voice,p_send); + +} +void SamplePlayer::set_reverb(VoiceID p_voice,ReverbRoomType p_room,float p_send) { + + _GET_VOICE + v.reverb_room=p_room; + v.reverb_send=p_send; + + AudioServer::get_singleton()->voice_set_reverb(v.voice,(AudioServer::ReverbRoomType)p_room,p_send); + +} + +#define _GET_VOICE_V(m_ret)\ + uint32_t voice=p_voice&0xFFFF;\ + ERR_FAIL_COND_V(voice > (uint32_t)voices.size(),m_ret);\ + const Voice &v=voices[voice];\ + if (v.check!=(p_voice>>16))\ + return m_ret;\ + ERR_FAIL_COND_V(!v.active,m_ret); + + +int SamplePlayer::get_mix_rate(VoiceID p_voice) const { + + _GET_VOICE_V(0); + + return v.mix_rate; +} +float SamplePlayer::get_pitch_scale(VoiceID p_voice) const { + + _GET_VOICE_V(0); + return v.sample_mix_rate/(float)v.mix_rate; +} +float SamplePlayer::get_volume(VoiceID p_voice) const { + + _GET_VOICE_V(0); + return v.volume; +} + + +float SamplePlayer::get_volume_db(VoiceID p_voice) const { + + _GET_VOICE_V(0); + return Math::linear2db(v.volume); +} + +float SamplePlayer::get_pan(VoiceID p_voice) const { + + _GET_VOICE_V(0); + return v.pan; +} +float SamplePlayer::get_pan_depth(VoiceID p_voice) const { + + + _GET_VOICE_V(0); + return v.pan_depth; +} +float SamplePlayer::get_pan_height(VoiceID p_voice) const { + + _GET_VOICE_V(0); + + return v.pan_height; +} +SamplePlayer::FilterType SamplePlayer::get_filter_type(VoiceID p_voice) const { + + _GET_VOICE_V(FILTER_NONE); + + return v.filter_type; +} +float SamplePlayer::get_filter_cutoff(VoiceID p_voice) const { + + _GET_VOICE_V(0); + + return v.filter_cutoff; +} +float SamplePlayer::get_filter_resonance(VoiceID p_voice) const { + + _GET_VOICE_V(0); + + return v.filter_resonance; +} + +float SamplePlayer::get_filter_gain(VoiceID p_voice) const { + + _GET_VOICE_V(0); + + return v.filter_gain; +} +float SamplePlayer::get_chorus(VoiceID p_voice) const { + + _GET_VOICE_V(0); + + return v.chorus_send; +} +float SamplePlayer::get_reverb_room(VoiceID p_voice) const { + + _GET_VOICE_V(0); + + return v.reverb_room; +} + +float SamplePlayer::get_reverb(VoiceID p_voice) const { + + _GET_VOICE_V(0); + + return v.reverb_send; +} + +bool SamplePlayer::is_voice_active(VoiceID p_voice) const { + + _GET_VOICE_V(false); + return v.active && AudioServer::get_singleton()->voice_is_active(v.voice); + +} +bool SamplePlayer::is_active() const { + + for(int i=0;i<voices.size();i++) { + + if (voices[i].active && AudioServer::get_singleton()->voice_is_active(voices[i].voice)) + return true; + + + } + + return false; +} + + + +void SamplePlayer::set_sample_library(const Ref<SampleLibrary>& p_library) { + + library=p_library; +} + +Ref<SampleLibrary> SamplePlayer::get_sample_library() const { + + return library; +} + + + +void SamplePlayer::set_default_pitch_scale(float p_pitch_scale) { + + _default.pitch_scale=p_pitch_scale; +} +void SamplePlayer::set_default_volume(float p_volume) { + + _default.volume_db=Math::linear2db(p_volume); +} +void SamplePlayer::set_default_volume_db(float p_db) { + + _default.volume_db=p_db; +} +void SamplePlayer::set_default_pan(float p_pan,float p_pan_depth,float p_pan_height) { + + _default.pan=p_pan; + _default.depth=p_pan_depth; + _default.height=p_pan_height; + +} +void SamplePlayer::set_default_filter(FilterType p_filter,float p_cutoff,float p_resonance,float p_gain) { + + _default.filter_type=p_filter; + _default.filter_cutoff=p_cutoff; + _default.filter_resonance=p_resonance; + _default.filter_gain=p_gain; +} +void SamplePlayer::set_default_chorus(float p_send) { + + _default.chorus_send=p_send; + +} +void SamplePlayer::set_default_reverb(ReverbRoomType p_room,float p_send) { + + _default.reverb_room=p_room; + _default.reverb_send=p_send; +} + +float SamplePlayer::get_default_volume() const { + + return Math::db2linear(_default.volume_db); +} +float SamplePlayer::get_default_volume_db() const { + + return _default.volume_db; +} +float SamplePlayer::get_default_pitch_scale() const { + + return _default.pitch_scale; +} + + +float SamplePlayer::get_default_pan() const { + + return _default.pan; +} +float SamplePlayer::get_default_pan_depth() const { + + return _default.depth; +} +float SamplePlayer::get_default_pan_height() const { + + return _default.height; +} +SamplePlayer::FilterType SamplePlayer::get_default_filter_type() const { + + return _default.filter_type; +} +float SamplePlayer::get_default_filter_cutoff() const { + + return _default.filter_cutoff; +} +float SamplePlayer::get_default_filter_resonance() const { + + return _default.filter_resonance; +} +float SamplePlayer::get_default_filter_gain() const { + + return _default.filter_gain; +} +float SamplePlayer::get_default_chorus() const { + + return _default.chorus_send; +} +float SamplePlayer::get_default_reverb_room() const { + + return _default.reverb_room; +} +float SamplePlayer::get_default_reverb() const { + + return _default.reverb_send; +} + + +void SamplePlayer::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_sample_library","library:SampleLibrary"),&SamplePlayer::set_sample_library ); + ObjectTypeDB::bind_method(_MD("get_sample_library:SampleLibrary"),&SamplePlayer::get_sample_library ); + + ObjectTypeDB::bind_method(_MD("set_voice_count","max_voices"),&SamplePlayer::set_voice_count ); + ObjectTypeDB::bind_method(_MD("get_voice_count"),&SamplePlayer::get_voice_count ); + + ObjectTypeDB::bind_method(_MD("play","name","unique"),&SamplePlayer::play, DEFVAL(false) ); + ObjectTypeDB::bind_method(_MD("stop","voice"),&SamplePlayer::stop ); + ObjectTypeDB::bind_method(_MD("stop_all"),&SamplePlayer::stop_all ); + + ObjectTypeDB::bind_method(_MD("set_mix_rate","voice","hz"),&SamplePlayer::set_mix_rate ); + ObjectTypeDB::bind_method(_MD("set_pitch_scale","voice","ratio"),&SamplePlayer::set_pitch_scale ); + ObjectTypeDB::bind_method(_MD("set_volume","voice","nrg"),&SamplePlayer::set_volume ); + ObjectTypeDB::bind_method(_MD("set_volume_db","voice","nrg"),&SamplePlayer::set_volume_db ); + ObjectTypeDB::bind_method(_MD("set_pan","voice","pan","depth","height"),&SamplePlayer::set_pan,DEFVAL(0),DEFVAL(0) ); + ObjectTypeDB::bind_method(_MD("set_filter","voice","type","cutoff_hz","resonance","gain"),&SamplePlayer::set_filter,DEFVAL(0) ); + ObjectTypeDB::bind_method(_MD("set_chorus","voice","send"),&SamplePlayer::set_chorus ); + ObjectTypeDB::bind_method(_MD("set_reverb","voice","room_type","send"),&SamplePlayer::set_reverb ); + + ObjectTypeDB::bind_method(_MD("get_mix_rate","voice"),&SamplePlayer::get_mix_rate ); + ObjectTypeDB::bind_method(_MD("get_pitch_scale","voice"),&SamplePlayer::get_pitch_scale ); + ObjectTypeDB::bind_method(_MD("get_volume","voice"),&SamplePlayer::get_volume ); + ObjectTypeDB::bind_method(_MD("get_volume_db","voice"),&SamplePlayer::get_volume_db ); + ObjectTypeDB::bind_method(_MD("get_pan","voice"),&SamplePlayer::get_pan ); + ObjectTypeDB::bind_method(_MD("get_pan_depth","voice"),&SamplePlayer::get_pan_depth ); + ObjectTypeDB::bind_method(_MD("get_pan_height","voice"),&SamplePlayer::get_pan_height ); + ObjectTypeDB::bind_method(_MD("get_filter_type","voice"),&SamplePlayer::get_filter_type ); + ObjectTypeDB::bind_method(_MD("get_filter_cutoff","voice"),&SamplePlayer::get_filter_cutoff ); + ObjectTypeDB::bind_method(_MD("get_filter_resonance","voice"),&SamplePlayer::get_filter_resonance ); + ObjectTypeDB::bind_method(_MD("get_filter_gain","voice"),&SamplePlayer::get_filter_gain ); + ObjectTypeDB::bind_method(_MD("get_chorus","voice"),&SamplePlayer::get_chorus ); + ObjectTypeDB::bind_method(_MD("get_reverb_room","voice"),&SamplePlayer::get_reverb_room ); + ObjectTypeDB::bind_method(_MD("get_reverb","voice"),&SamplePlayer::get_reverb ); + + ObjectTypeDB::bind_method(_MD("set_default_pitch_scale","ratio"),&SamplePlayer::set_default_pitch_scale ); + ObjectTypeDB::bind_method(_MD("set_default_volume","nrg"),&SamplePlayer::set_default_volume ); + ObjectTypeDB::bind_method(_MD("set_default_volume_db","db"),&SamplePlayer::set_default_volume ); + ObjectTypeDB::bind_method(_MD("set_default_pan","pan","depth","height"),&SamplePlayer::set_default_pan,DEFVAL(0),DEFVAL(0) ); + ObjectTypeDB::bind_method(_MD("set_default_filter","type","cutoff_hz","resonance","gain"),&SamplePlayer::set_default_filter,DEFVAL(0) ); + ObjectTypeDB::bind_method(_MD("set_default_chorus","send"),&SamplePlayer::set_default_chorus ); + ObjectTypeDB::bind_method(_MD("set_default_reverb","room_type","send"),&SamplePlayer::set_default_reverb ); + + ObjectTypeDB::bind_method(_MD("get_default_pitch_scale"),&SamplePlayer::get_default_pitch_scale ); + ObjectTypeDB::bind_method(_MD("get_default_volume"),&SamplePlayer::get_default_volume ); + ObjectTypeDB::bind_method(_MD("get_default_volume_db"),&SamplePlayer::get_default_volume ); + ObjectTypeDB::bind_method(_MD("get_default_pan"),&SamplePlayer::get_default_pan ); + ObjectTypeDB::bind_method(_MD("get_default_pan_depth"),&SamplePlayer::get_default_pan_depth ); + ObjectTypeDB::bind_method(_MD("get_default_pan_height"),&SamplePlayer::get_default_pan_height ); + ObjectTypeDB::bind_method(_MD("get_default_filter_type"),&SamplePlayer::get_default_filter_type ); + ObjectTypeDB::bind_method(_MD("get_default_filter_cutoff"),&SamplePlayer::get_default_filter_cutoff ); + ObjectTypeDB::bind_method(_MD("get_default_filter_resonance"),&SamplePlayer::get_default_filter_resonance ); + ObjectTypeDB::bind_method(_MD("get_default_filter_gain"),&SamplePlayer::get_default_filter_gain ); + ObjectTypeDB::bind_method(_MD("get_default_chorus"),&SamplePlayer::get_default_chorus ); + ObjectTypeDB::bind_method(_MD("get_default_reverb_room"),&SamplePlayer::get_default_reverb_room ); + ObjectTypeDB::bind_method(_MD("get_default_reverb"),&SamplePlayer::get_default_reverb ); + + ObjectTypeDB::bind_method(_MD("is_active"),&SamplePlayer::is_active ); + ObjectTypeDB::bind_method(_MD("is_voice_active","voice"),&SamplePlayer::is_voice_active ); + + BIND_CONSTANT( FILTER_NONE); + BIND_CONSTANT( FILTER_LOWPASS); + BIND_CONSTANT( FILTER_BANDPASS); + BIND_CONSTANT( FILTER_HIPASS); + BIND_CONSTANT( FILTER_NOTCH); + BIND_CONSTANT( FILTER_PEAK); + BIND_CONSTANT( FILTER_BANDLIMIT); ///< cutoff is LP resonace is HP + BIND_CONSTANT( FILTER_LOW_SHELF); + BIND_CONSTANT( FILTER_HIGH_SHELF); + + BIND_CONSTANT( REVERB_SMALL ); + BIND_CONSTANT( REVERB_MEDIUM ); + BIND_CONSTANT( REVERB_LARGE ); + BIND_CONSTANT( REVERB_HALL ); + +} + + +SamplePlayer::SamplePlayer() { + + voices.resize(1); + + _default.pitch_scale=1; + _default.volume_db=0; + _default.pan=0; + _default.depth=0; + _default.height=0; + _default.filter_type=FILTER_NONE; + _default.filter_cutoff=5000; + _default.filter_resonance=1; + _default.filter_gain=1; + _default.chorus_send=0; + _default.reverb_room=REVERB_LARGE; + _default.reverb_send=0; + last_id=0; + last_check=0; + + +} + +SamplePlayer::~SamplePlayer() { + + +} diff --git a/scene/audio/sample_player.h b/scene/audio/sample_player.h new file mode 100644 index 000000000..d0ce1825e --- /dev/null +++ b/scene/audio/sample_player.h @@ -0,0 +1,198 @@ +/*************************************************************************/ +/* sample_player.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef SAMPLE_PLAYER_H +#define SAMPLE_PLAYER_H + +#include "scene/main/node.h" +#include "scene/resources/sample_library.h" + +class SamplePlayer : public Node { + + OBJ_TYPE( SamplePlayer, Node ); + OBJ_CATEGORY("Audio Nodes"); +public: + + + enum FilterType { + FILTER_NONE, + FILTER_LOWPASS, + FILTER_BANDPASS, + FILTER_HIPASS, + FILTER_NOTCH, + FILTER_PEAK, + FILTER_BANDLIMIT, ///< cutoff is LP resonace is HP + FILTER_LOW_SHELF, + FILTER_HIGH_SHELF, + }; + + enum ReverbRoomType { + + REVERB_SMALL, + REVERB_MEDIUM, + REVERB_LARGE, + REVERB_HALL + }; + + enum { + + INVALID_VOICE_ID=0xFFFFFFFF + }; + + typedef uint32_t VoiceID; + +private: + + Ref<SampleLibrary> library; + + struct Voice { + + RID voice; + uint32_t check; + bool active; + + int sample_mix_rate; + int mix_rate; + float volume; + float pan; + float pan_depth; + float pan_height; + FilterType filter_type; + float filter_cutoff; + float filter_resonance; + float filter_gain; + float chorus_send; + ReverbRoomType reverb_room; + float reverb_send; + + void clear(); + Voice(); + ~Voice(); + }; + + Vector<Voice> voices; + + struct Default { + + float reverb_send; + float pitch_scale; + float volume_db; + float pan; + float depth; + float height; + FilterType filter_type; + float filter_cutoff; + float filter_resonance; + float filter_gain; + float chorus_send; + ReverbRoomType reverb_room; + + } _default; + + uint32_t last_id; + uint16_t last_check; + String played_back; +protected: + + bool _set(const StringName& p_name, const Variant& p_value); + bool _get(const StringName& p_name,Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + + static void _bind_methods(); + +public: + + void set_sample_library(const Ref<SampleLibrary>& p_library); + Ref<SampleLibrary> get_sample_library() const; + + void set_voice_count(int p_voice_count); + int get_voice_count() const; + + VoiceID play(const String& p_name,bool unique=false); + void stop(VoiceID p_voice); + void stop_all(); + bool is_voice_active(VoiceID) const; + bool is_active() const; + + void set_mix_rate(VoiceID p_voice, int p_mix_rate); + void set_pitch_scale(VoiceID p_voice, float p_pitch_scale); + void set_volume(VoiceID p_voice, float p_volume); + void set_volume_db(VoiceID p_voice, float p_db); + void set_pan(VoiceID p_voice, float p_pan,float p_pan_depth=0,float p_pan_height=0); + void set_filter(VoiceID p_voice,FilterType p_filter,float p_cutoff,float p_resonance,float p_gain); + void set_chorus(VoiceID p_voice,float p_send); + void set_reverb(VoiceID p_voice,ReverbRoomType p_room,float p_send); + + int get_mix_rate(VoiceID p_voice) const; + float get_pitch_scale(VoiceID p_voice) const; + float get_volume(VoiceID p_voice) const; + float get_volume_db(VoiceID p_voice) const; + + float get_pan(VoiceID p_voice) const; + float get_pan_depth(VoiceID p_voice) const; + float get_pan_height(VoiceID p_voice) const; + FilterType get_filter_type(VoiceID p_voice) const; + float get_filter_cutoff(VoiceID p_voice) const; + float get_filter_resonance(VoiceID p_voice) const; + float get_filter_gain(VoiceID p_voice) const; + float get_chorus(VoiceID p_voice) const; + float get_reverb_room(VoiceID p_voice) const; + float get_reverb(VoiceID p_voice) const; + + + + void set_default_pitch_scale(float p_pitch_scale); + void set_default_volume(float p_volume); + void set_default_volume_db(float p_db); + void set_default_pan(float p_pan,float p_pan_depth=0,float p_pan_height=0); + void set_default_filter(FilterType p_filter,float p_cutoff,float p_resonance,float p_gain); + void set_default_chorus(float p_send); + void set_default_reverb(ReverbRoomType p_room,float p_send); + + float get_default_volume() const; + float get_default_volume_db() const; + float get_default_pitch_scale() const; + float get_default_pan() const; + float get_default_pan_depth() const; + float get_default_pan_height() const; + FilterType get_default_filter_type() const; + float get_default_filter_cutoff() const; + float get_default_filter_resonance() const; + float get_default_filter_gain() const; + float get_default_chorus() const; + float get_default_reverb_room() const; + float get_default_reverb() const; + + SamplePlayer(); + ~SamplePlayer(); +}; + +VARIANT_ENUM_CAST( SamplePlayer::FilterType ); +VARIANT_ENUM_CAST( SamplePlayer::ReverbRoomType ); + +#endif // SAMPLE_PLAYER_H diff --git a/scene/audio/sound_room_params.cpp b/scene/audio/sound_room_params.cpp new file mode 100644 index 000000000..3e0a64b3f --- /dev/null +++ b/scene/audio/sound_room_params.cpp @@ -0,0 +1,180 @@ +/*************************************************************************/ +/* sound_room_params.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "sound_room_params.h" + +#include "scene/main/viewport.h" + +#ifndef _3D_DISABLED +void SoundRoomParams::_update_sound_room() { + + if (!room.is_valid()) + return; + + for(int i=0;i<PARAM_MAX;i++) { + + SpatialSoundServer::get_singleton()->room_set_param(room,SpatialSoundServer::RoomParam(i),params[i]); + + } + + SpatialSoundServer::get_singleton()->room_set_reverb(room,SpatialSoundServer::RoomReverb(reverb)); + SpatialSoundServer::get_singleton()->room_set_force_params_to_all_sources(room,force_params_for_all_sources); +} + + +void SoundRoomParams::_notification(int p_what) { + + + switch(p_what) { + + + case NOTIFICATION_ENTER_SCENE: { +#if 0 + Node *n=this; + Room *room_instance=NULL; + while(n) { + + room_instance=n->cast_to<Room>(); + if (room_instance) { + + break; + } + if (n->cast_to<Viewport>()) + break; + + n=n->get_parent(); + } + + + if (room_instance) { + room=room_instance->get_sound_room(); + } else { + room=get_scene()->get_default_world()->get_sound_space(); + } + + _update_sound_room(); +#endif + + } break; + case NOTIFICATION_EXIT_SCENE: { + + room=RID(); + + } break; + } +} + + +void SoundRoomParams::set_param(Params p_param, float p_value) { + + ERR_FAIL_INDEX(p_param,PARAM_MAX); + params[p_param]=p_value; + if (room.is_valid()) + SpatialSoundServer::get_singleton()->room_set_param(room,SpatialSoundServer::RoomParam(p_param),p_value); +} + +float SoundRoomParams::get_param(Params p_param) const { + + ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0); + return params[p_param]; +} + + +void SoundRoomParams::set_reverb_mode(Reverb p_mode) { + + ERR_FAIL_INDEX(p_mode,4); + reverb=p_mode; + if (room.is_valid()) + SpatialSoundServer::get_singleton()->room_set_reverb(room,SpatialSoundServer::RoomReverb(p_mode)); +} + +SoundRoomParams::Reverb SoundRoomParams::get_reverb_mode() const { + + return reverb; +} + + +void SoundRoomParams::set_force_params_to_all_sources(bool p_force) { + + force_params_for_all_sources=p_force; + if (room.is_valid()) + SpatialSoundServer::get_singleton()->room_set_force_params_to_all_sources(room,p_force); +} + +bool SoundRoomParams::is_forcing_params_to_all_sources() { + + return force_params_for_all_sources; +} + + +void SoundRoomParams::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_param","param","value"),&SoundRoomParams::set_param ); + ObjectTypeDB::bind_method(_MD("get_param","param"),&SoundRoomParams::get_param ); + + ObjectTypeDB::bind_method(_MD("set_reverb_mode","reverb_mode","value"),&SoundRoomParams::set_reverb_mode ); + ObjectTypeDB::bind_method(_MD("get_reverb_mode","reverb_mode"),&SoundRoomParams::get_reverb_mode ); + + ObjectTypeDB::bind_method(_MD("set_force_params_to_all_sources","enabled"),&SoundRoomParams::set_force_params_to_all_sources ); + ObjectTypeDB::bind_method(_MD("is_forcing_params_to_all_sources"),&SoundRoomParams::is_forcing_params_to_all_sources ); + + + ADD_PROPERTY( PropertyInfo( Variant::INT, "reverb/mode", PROPERTY_HINT_ENUM, "Small,Medium,Large,Hall"), _SCS("set_reverb_mode"), _SCS("get_reverb_mode") ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/speed_of_scale", PROPERTY_HINT_RANGE, "0.01,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SPEED_OF_SOUND_SCALE); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/doppler_factor",PROPERTY_HINT_RANGE, "0.01,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_DOPPLER_FACTOR ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/pitch_scale",PROPERTY_HINT_RANGE, "0.01,32,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_PITCH_SCALE ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/volume_scale_db",PROPERTY_HINT_RANGE, "-80,24,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_VOLUME_SCALE_DB ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/reverb_send",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_REVERB_SEND ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/chorus_send",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_CHORUS_SEND ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation_scale",PROPERTY_HINT_RANGE, "0.01,32,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION_SCALE ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation_hf_cutoff",PROPERTY_HINT_RANGE, "30,16384,1"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION_HF_CUTOFF ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation_hf_floor_db",PROPERTY_HINT_RANGE, "-80,24,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION_HF_FLOOR_DB ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation_hf_ratio_exp",PROPERTY_HINT_RANGE, "0.01,32,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION_HF_RATIO_EXP ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation_reverb_scale",PROPERTY_HINT_RANGE, "0.01,32,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION_REVERB_SCALE ); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "force_to_all_sources"),_SCS("set_force_params_to_all_sources"),_SCS("is_forcing_params_to_all_sources") ); + +} + + +SoundRoomParams::SoundRoomParams() { + + reverb=REVERB_HALL; + params[PARAM_SPEED_OF_SOUND_SCALE]=1; + params[PARAM_DOPPLER_FACTOR]=1.0; + params[PARAM_PITCH_SCALE]=1.0; + params[PARAM_VOLUME_SCALE_DB]=0; + params[PARAM_REVERB_SEND]=0; + params[PARAM_CHORUS_SEND]=0; + params[PARAM_ATTENUATION_SCALE]=1.0; + params[PARAM_ATTENUATION_HF_CUTOFF]=5000; + params[PARAM_ATTENUATION_HF_FLOOR_DB]=-24.0; + params[PARAM_ATTENUATION_HF_RATIO_EXP]=1.0; + params[PARAM_ATTENUATION_REVERB_SCALE]=0.0; + force_params_for_all_sources=false; +} +#endif diff --git a/scene/audio/sound_room_params.h b/scene/audio/sound_room_params.h new file mode 100644 index 000000000..5999046b8 --- /dev/null +++ b/scene/audio/sound_room_params.h @@ -0,0 +1,100 @@ +/*************************************************************************/ +/* sound_room_params.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef SOUND_ROOM_PARAMS_H +#define SOUND_ROOM_PARAMS_H + +#include "scene/main/node.h" +#include "servers/spatial_sound_server.h" + + +#ifndef _3D_DISABLED + +#include "scene/3d/room_instance.h" +class SoundRoomParams : public Node { + + OBJ_TYPE( SoundRoomParams, Node ); +public: + + enum Params { + PARAM_SPEED_OF_SOUND_SCALE=SpatialSoundServer::ROOM_PARAM_SPEED_OF_SOUND_SCALE, + PARAM_DOPPLER_FACTOR=SpatialSoundServer::ROOM_PARAM_DOPPLER_FACTOR, + PARAM_PITCH_SCALE=SpatialSoundServer::ROOM_PARAM_PITCH_SCALE, + PARAM_VOLUME_SCALE_DB=SpatialSoundServer::ROOM_PARAM_VOLUME_SCALE_DB, + PARAM_REVERB_SEND=SpatialSoundServer::ROOM_PARAM_REVERB_SEND, + PARAM_CHORUS_SEND=SpatialSoundServer::ROOM_PARAM_CHORUS_SEND, + PARAM_ATTENUATION_SCALE=SpatialSoundServer::ROOM_PARAM_ATTENUATION_SCALE, + PARAM_ATTENUATION_HF_CUTOFF=SpatialSoundServer::ROOM_PARAM_ATTENUATION_HF_CUTOFF, + PARAM_ATTENUATION_HF_FLOOR_DB=SpatialSoundServer::ROOM_PARAM_ATTENUATION_HF_FLOOR_DB, + PARAM_ATTENUATION_HF_RATIO_EXP=SpatialSoundServer::ROOM_PARAM_ATTENUATION_HF_RATIO_EXP, + PARAM_ATTENUATION_REVERB_SCALE=SpatialSoundServer::ROOM_PARAM_ATTENUATION_REVERB_SCALE, + PARAM_MAX=SpatialSoundServer::ROOM_PARAM_MAX + }; + + enum Reverb { + REVERB_SMALL, + REVERB_MEDIUM, + REVERB_LARGE, + REVERB_HALL + }; +private: + + RID room; + + float params[PARAM_MAX]; + Reverb reverb; + bool force_params_for_all_sources; + void _update_sound_room(); + + +protected: + + void _notification(int p_what); + static void _bind_methods(); + +public: + + + void set_param(Params p_param, float p_value); + float get_param(Params p_param) const; + + void set_reverb_mode(Reverb p_mode); + Reverb get_reverb_mode() const; + + void set_force_params_to_all_sources(bool p_force); + bool is_forcing_params_to_all_sources(); + + SoundRoomParams(); +}; + +VARIANT_ENUM_CAST(SoundRoomParams::Params); +VARIANT_ENUM_CAST(SoundRoomParams::Reverb); + +#endif + +#endif // SOUND_ROOM_PARAMS_H diff --git a/scene/audio/stream_player.cpp b/scene/audio/stream_player.cpp new file mode 100644 index 000000000..5084c1295 --- /dev/null +++ b/scene/audio/stream_player.cpp @@ -0,0 +1,290 @@ +/*************************************************************************/ +/* stream_player.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "stream_player.h" + + +void StreamPlayer::_notification(int p_what) { + + switch(p_what) { + + case NOTIFICATION_ENTER_SCENE: { + + //set_idle_process(false); //don't annoy + if (stream.is_valid() && autoplay && !get_scene()->is_editor_hint()) + play(); + } break; + case NOTIFICATION_EXIT_SCENE: { + + stop(); //wathever it may be doing, stop + } break; + } +} + + + +void StreamPlayer::set_stream(const Ref<AudioStream> &p_stream) { + + stop(); + + if (stream_rid.is_valid()) + AudioServer::get_singleton()->free(stream_rid); + stream_rid=RID(); + + stream=p_stream; + if (!stream.is_null()) { + + stream->set_loop(loops); + stream->set_paused(paused); + stream_rid=AudioServer::get_singleton()->audio_stream_create(stream->get_audio_stream()); + } + + +} + +Ref<AudioStream> StreamPlayer::get_stream() const { + + return stream; +} + + +void StreamPlayer::play() { + + ERR_FAIL_COND(!is_inside_scene()); + if (stream.is_null()) + return; + if (stream->is_playing()) + stop(); + + stream->play(); + AudioServer::get_singleton()->stream_set_active(stream_rid,true); + AudioServer::get_singleton()->stream_set_volume_scale(stream_rid,volume); +// if (stream->get_update_mode()!=AudioStream::UPDATE_NONE) +// set_idle_process(true); + +} + +void StreamPlayer::stop() { + + if (!is_inside_scene()) + return; + if (stream.is_null()) + return; + + AudioServer::get_singleton()->stream_set_active(stream_rid,false); + stream->stop(); + //set_idle_process(false); +} + +bool StreamPlayer::is_playing() const { + + if (stream.is_null()) + return false; + + return stream->is_playing(); +} + +void StreamPlayer::set_loop(bool p_enable) { + + loops=p_enable; + if (stream.is_null()) + return; + stream->set_loop(loops); + +} +bool StreamPlayer::has_loop() const { + + return loops; +} + +void StreamPlayer::set_volume(float p_vol) { + + volume=p_vol; + if (stream_rid.is_valid()) + AudioServer::get_singleton()->stream_set_volume_scale(stream_rid,volume); +} + +float StreamPlayer::get_volume() const { + + return volume; +} + +void StreamPlayer::set_volume_db(float p_db) { + + if (p_db<-79) + set_volume(0); + else + set_volume(Math::db2linear(p_db)); +} + +float StreamPlayer::get_volume_db() const { + + if (volume==0) + return -80; + else + return Math::linear2db(volume); +} + + +String StreamPlayer::get_stream_name() const { + + if (stream.is_null()) + return "<No Stream>"; + return stream->get_name(); + +} + +int StreamPlayer::get_loop_count() const { + + if (stream.is_null()) + return 0; + return stream->get_loop_count(); + +} + +float StreamPlayer::get_pos() const { + + if (stream.is_null()) + return 0; + return stream->get_pos(); + +} + +float StreamPlayer::get_length() const { + + if (stream.is_null()) + return 0; + return stream->get_length(); +} +void StreamPlayer::seek_pos(float p_time) { + + if (stream.is_null()) + return; + return stream->seek_pos(p_time); + +} + +void StreamPlayer::set_autoplay(bool p_enable) { + + autoplay=p_enable; +} + +bool StreamPlayer::has_autoplay() const { + + return autoplay; +} + +void StreamPlayer::set_paused(bool p_paused) { + + paused=p_paused; + if (stream.is_valid()) + stream->set_paused(p_paused); +} + +bool StreamPlayer::is_paused() const { + + return paused; +} + +void StreamPlayer::_set_play(bool p_play) { + + _play=p_play; + if (is_inside_scene()) { + if(_play) + play(); + else + stop(); + } + +} + +bool StreamPlayer::_get_play() const{ + + return _play; +} + + +void StreamPlayer::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_stream","stream:Stream"),&StreamPlayer::set_stream); + ObjectTypeDB::bind_method(_MD("get_stream:Stream"),&StreamPlayer::get_stream); + + ObjectTypeDB::bind_method(_MD("play"),&StreamPlayer::play); + ObjectTypeDB::bind_method(_MD("stop"),&StreamPlayer::stop); + + ObjectTypeDB::bind_method(_MD("is_playing"),&StreamPlayer::is_playing); + + ObjectTypeDB::bind_method(_MD("set_paused","paused"),&StreamPlayer::set_paused); + ObjectTypeDB::bind_method(_MD("is_paused"),&StreamPlayer::is_paused); + + ObjectTypeDB::bind_method(_MD("set_loop","enabled"),&StreamPlayer::set_loop); + ObjectTypeDB::bind_method(_MD("has_loop"),&StreamPlayer::has_loop); + + ObjectTypeDB::bind_method(_MD("set_volume","volume"),&StreamPlayer::set_volume); + ObjectTypeDB::bind_method(_MD("get_volume"),&StreamPlayer::get_volume); + + ObjectTypeDB::bind_method(_MD("set_volume_db","db"),&StreamPlayer::set_volume_db); + ObjectTypeDB::bind_method(_MD("get_volume_db"),&StreamPlayer::get_volume_db); + + ObjectTypeDB::bind_method(_MD("get_stream_name"),&StreamPlayer::get_stream_name); + ObjectTypeDB::bind_method(_MD("get_loop_count"),&StreamPlayer::get_loop_count); + + ObjectTypeDB::bind_method(_MD("get_pos"),&StreamPlayer::get_pos); + ObjectTypeDB::bind_method(_MD("seek_pos","time"),&StreamPlayer::seek_pos); + + ObjectTypeDB::bind_method(_MD("set_autoplay","enabled"),&StreamPlayer::set_autoplay); + ObjectTypeDB::bind_method(_MD("has_autoplay"),&StreamPlayer::has_autoplay); + + ObjectTypeDB::bind_method(_MD("get_length"),&StreamPlayer::get_length); + + ObjectTypeDB::bind_method(_MD("_set_play","play"),&StreamPlayer::_set_play); + ObjectTypeDB::bind_method(_MD("_get_play"),&StreamPlayer::_get_play); + + ADD_PROPERTY( PropertyInfo(Variant::OBJECT, "stream/stream", PROPERTY_HINT_RESOURCE_TYPE,"AudioStream"), _SCS("set_stream"), _SCS("get_stream") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/play"), _SCS("_set_play"), _SCS("_get_play") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/loop"), _SCS("set_loop"), _SCS("has_loop") ); + ADD_PROPERTY( PropertyInfo(Variant::REAL, "stream/volume_db", PROPERTY_HINT_RANGE,"-80,24,0.01"), _SCS("set_volume_db"), _SCS("get_volume_db") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/autoplay"), _SCS("set_autoplay"), _SCS("has_autoplay") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/paused"), _SCS("set_paused"), _SCS("is_paused") ); +} + + +StreamPlayer::StreamPlayer() { + + volume=1; + loops=false; + paused=false; + autoplay=false; + _play=false; +} + +StreamPlayer::~StreamPlayer() { + if (stream_rid.is_valid()) + AudioServer::get_singleton()->free(stream_rid); + +} diff --git a/scene/audio/stream_player.h b/scene/audio/stream_player.h new file mode 100644 index 000000000..945d615d6 --- /dev/null +++ b/scene/audio/stream_player.h @@ -0,0 +1,89 @@ +/*************************************************************************/ +/* stream_player.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef STREAM_PLAYER_H +#define STREAM_PLAYER_H + +#include "scene/resources/audio_stream.h" +#include "scene/main/node.h" + +class StreamPlayer : public Node { + + OBJ_TYPE(StreamPlayer,Node); + + Ref<AudioStream> stream; + RID stream_rid; + bool paused; + bool autoplay; + bool loops; + float volume; + + bool _play; + void _set_play(bool p_play); + bool _get_play() const; +protected: + void _notification(int p_what); + + static void _bind_methods(); +public: + + void set_stream(const Ref<AudioStream> &p_stream); + Ref<AudioStream> get_stream() const; + + void play(); + void stop(); + bool is_playing() const; + + void set_paused(bool p_paused); + bool is_paused() const; + + void set_loop(bool p_enable); + bool has_loop() const; + + void set_volume(float p_vol); + float get_volume() const; + + void set_volume_db(float p_db); + float get_volume_db() const; + + String get_stream_name() const; + + int get_loop_count() const; + + float get_pos() const; + void seek_pos(float p_time); + float get_length() const; + void set_autoplay(bool p_vol); + bool has_autoplay() const; + + + StreamPlayer(); + ~StreamPlayer(); +}; + +#endif // AUDIO_STREAM_PLAYER_H |
