diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp index 31bf5ac292f..4b4c57fbdd1 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp @@ -17,7 +17,7 @@ void AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame* p_buffer,int p_fram if (todo) { //end of file! - if (false) { + if (vorbis_stream->loop) { //loop seek_pos(0); loops++; @@ -120,9 +120,9 @@ String AudioStreamOGGVorbis::get_stream_name() const { return "";//return stream_name; } -Error AudioStreamOGGVorbis::setup(const uint8_t *p_data,uint32_t p_data_len) { - +void AudioStreamOGGVorbis::set_data(const PoolVector& p_data) { + int src_data_len=p_data.size(); #define MAX_TEST_MEM (1<<20) uint32_t alloc_try=1024; @@ -139,37 +139,81 @@ Error AudioStreamOGGVorbis::setup(const uint8_t *p_data,uint32_t p_data_len) { ogg_alloc.alloc_buffer=w.ptr(); ogg_alloc.alloc_buffer_length_in_bytes=alloc_try; + PoolVector::Read src_datar = p_data.read(); + int error; - ogg_stream = stb_vorbis_open_memory( (const unsigned char*)p_data, p_data_len, &error, &ogg_alloc ); + ogg_stream = stb_vorbis_open_memory( (const unsigned char*)src_datar.ptr(), src_data_len, &error, &ogg_alloc ); if (!ogg_stream && error==VORBIS_outofmem) { w = PoolVector::Write(); alloc_try*=2; } else { + + ERR_FAIL_COND(alloc_try==MAX_TEST_MEM); + ERR_FAIL_COND(ogg_stream==NULL); + + stb_vorbis_info info = stb_vorbis_get_info(ogg_stream); + + channels = info.channels; + sample_rate = info.sample_rate; + decode_mem_size = alloc_try; + //does this work? (it's less mem..) + //decode_mem_size = ogg_alloc.alloc_buffer_length_in_bytes + info.setup_memory_required + info.temp_memory_required + info.max_frame_size; + + //print_line("succeded "+itos(ogg_alloc.alloc_buffer_length_in_bytes)+" setup "+itos(info.setup_memory_required)+" setup temp "+itos(info.setup_temp_memory_required)+" temp "+itos(info.temp_memory_required)+" maxframe"+itos(info.max_frame_size)); + + length=stb_vorbis_stream_length_in_seconds(ogg_stream); + stb_vorbis_close(ogg_stream); + + data = AudioServer::get_singleton()->audio_data_alloc(src_data_len,src_datar.ptr()); + data_len=src_data_len; + break; } } - ERR_FAIL_COND_V(alloc_try==MAX_TEST_MEM,ERR_OUT_OF_MEMORY); - ERR_FAIL_COND_V(ogg_stream==NULL,ERR_FILE_CORRUPT); - stb_vorbis_info info = stb_vorbis_get_info(ogg_stream); - - channels = info.channels; - sample_rate = info.sample_rate; - decode_mem_size = alloc_try; - //does this work? (it's less mem..) - //decode_mem_size = ogg_alloc.alloc_buffer_length_in_bytes + info.setup_memory_required + info.temp_memory_required + info.max_frame_size; - - //print_line("succeded "+itos(ogg_alloc.alloc_buffer_length_in_bytes)+" setup "+itos(info.setup_memory_required)+" setup temp "+itos(info.setup_temp_memory_required)+" temp "+itos(info.temp_memory_required)+" maxframe"+itos(info.max_frame_size)); - - length=stb_vorbis_stream_length_in_seconds(ogg_stream); - stb_vorbis_close(ogg_stream); - - data = AudioServer::get_singleton()->audio_data_alloc(p_data_len,p_data); - data_len=p_data_len; printf("create at %p, data %p\n",this,data); - return OK; + +} + +PoolVector AudioStreamOGGVorbis::get_data() const { + + PoolVector vdata; + + if (data_len && data) { + vdata.resize(data_len); + { + PoolVector::Write w = vdata.write(); + copymem(w.ptr(),data,data_len); + } + + } + + return vdata; +} + +void AudioStreamOGGVorbis::set_loop(bool p_enable) { + loop=p_enable; +} + +bool AudioStreamOGGVorbis::has_loop() const { + + return loop; +} + + +void AudioStreamOGGVorbis::_bind_methods() { + + ClassDB::bind_method(_MD("set_data","data"),&AudioStreamOGGVorbis::set_data); + ClassDB::bind_method(_MD("get_data"),&AudioStreamOGGVorbis::get_data); + + ClassDB::bind_method(_MD("set_loop","enable"),&AudioStreamOGGVorbis::set_loop); + ClassDB::bind_method(_MD("has_loop"),&AudioStreamOGGVorbis::has_loop); + + ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY,"data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_data"),_SCS("get_data")); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"loop",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_loop"),_SCS("has_loop")); + } AudioStreamOGGVorbis::AudioStreamOGGVorbis() { @@ -180,57 +224,9 @@ AudioStreamOGGVorbis::AudioStreamOGGVorbis() { sample_rate=1; channels=1; decode_mem_size=0; + loop=false; } -RES ResourceFormatLoaderAudioStreamOGGVorbis::load(const String &p_path, const String& p_original_path, Error *r_error) { - if (r_error) - *r_error=OK; - - FileAccess *f = FileAccess::open(p_path,FileAccess::READ); - if (!f) { - *r_error=ERR_CANT_OPEN; - ERR_FAIL_COND_V(!f,RES()); - } - - size_t len = f->get_len(); - - PoolVector data; - data.resize(len); - PoolVector::Write w = data.write(); - - f->get_buffer(w.ptr(),len); - - memdelete(f); - - Ref ogg_stream; - ogg_stream.instance(); - - Error err = ogg_stream->setup(w.ptr(),len); - - if (err!=OK) { - *r_error=err; - ogg_stream.unref(); - ERR_FAIL_V(RES()); - } - - return ogg_stream; -} - -void ResourceFormatLoaderAudioStreamOGGVorbis::get_recognized_extensions(List *p_extensions) const { - - p_extensions->push_back("ogg"); -} -String ResourceFormatLoaderAudioStreamOGGVorbis::get_resource_type(const String &p_path) const { - - if (p_path.get_extension().to_lower()=="ogg") - return "AudioStreamOGGVorbis"; - return ""; -} - -bool ResourceFormatLoaderAudioStreamOGGVorbis::handles_type(const String& p_type) const { - return (p_type=="AudioStream" || p_type=="AudioStreamOGG" || p_type=="AudioStreamOGGVorbis"); -} - diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.h b/modules/stb_vorbis/audio_stream_ogg_vorbis.h index 4555423f852..21ce23740c1 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.h +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.h @@ -49,6 +49,7 @@ class AudioStreamOGGVorbis : public AudioStream { GDCLASS( AudioStreamOGGVorbis, AudioStream ) OBJ_SAVE_TYPE( AudioStream ) //children are all saved as AudioStream, so they can be exchanged + RES_BASE_EXTENSION("asogg"); friend class AudioStreamPlaybackOGGVorbis; @@ -59,26 +60,24 @@ friend class AudioStreamPlaybackOGGVorbis; float sample_rate; int channels; float length; + bool loop; +protected: + static void _bind_methods(); public: + void set_loop(bool p_enable); + bool has_loop() const; virtual Ref instance_playback(); virtual String get_stream_name() const; - Error setup(const uint8_t *p_data, uint32_t p_data_len); + void set_data(const PoolVector& p_data); + PoolVector get_data() const; AudioStreamOGGVorbis(); }; -class ResourceFormatLoaderAudioStreamOGGVorbis : public ResourceFormatLoader { -public: - virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL); - virtual void get_recognized_extensions(List *p_extensions) const; - virtual bool handles_type(const String& p_type) const; - virtual String get_resource_type(const String &p_path) const; -}; - #endif diff --git a/modules/stb_vorbis/register_types.cpp b/modules/stb_vorbis/register_types.cpp index 143ad6f47e9..41fbc6fbd71 100644 --- a/modules/stb_vorbis/register_types.cpp +++ b/modules/stb_vorbis/register_types.cpp @@ -28,17 +28,18 @@ /*************************************************************************/ #include "register_types.h" #include "audio_stream_ogg_vorbis.h" - -static ResourceFormatLoaderAudioStreamOGGVorbis *vorbis_stream_loader = NULL; +#include "resource_importer_ogg_vorbis.h" void register_stb_vorbis_types() { - vorbis_stream_loader = memnew( ResourceFormatLoaderAudioStreamOGGVorbis ); - ResourceLoader::add_resource_format_loader(vorbis_stream_loader); +#ifdef TOOLS_ENABLED + Ref ogg_import; + ogg_import.instance(); + ResourceFormatImporter::get_singleton()->add_importer(ogg_import); +#endif ClassDB::register_class(); } void unregister_stb_vorbis_types() { - memdelete( vorbis_stream_loader ); } diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp new file mode 100644 index 00000000000..6f90c8587b9 --- /dev/null +++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp @@ -0,0 +1,84 @@ +#include "resource_importer_ogg_vorbis.h" + +#include "io/resource_saver.h" +#include "os/file_access.h" +#include "scene/resources/texture.h" + +String ResourceImporterOGGVorbis::get_importer_name() const { + + return "ogg_vorbis"; +} + +String ResourceImporterOGGVorbis::get_visible_name() const{ + + return "OGGVorbis"; +} +void ResourceImporterOGGVorbis::get_recognized_extensions(List *p_extensions) const{ + + p_extensions->push_back("ogg"); +} + +String ResourceImporterOGGVorbis::get_save_extension() const { + return "asogg"; +} + +String ResourceImporterOGGVorbis::get_resource_type() const{ + + return "AudioStreamOGGVorbis"; +} + +bool ResourceImporterOGGVorbis::get_option_visibility(const String& p_option,const Map& p_options) const { + + return true; +} + +int ResourceImporterOGGVorbis::get_preset_count() const { + return 0; +} +String ResourceImporterOGGVorbis::get_preset_name(int p_idx) const { + + return String(); +} + + +void ResourceImporterOGGVorbis::get_import_options(List *r_options,int p_preset) const { + + + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"loop"),true)); + +} + + + +Error ResourceImporterOGGVorbis::import(const String& p_source_file, const String& p_save_path, const Map& p_options, List* r_platform_variants, List *r_gen_files) { + + bool loop = p_options["loop"]; + + FileAccess *f = FileAccess::open(p_source_file,FileAccess::READ); + if (!f) { + ERR_FAIL_COND_V(!f,ERR_CANT_OPEN); + } + + size_t len = f->get_len(); + + PoolVector data; + data.resize(len); + PoolVector::Write w = data.write(); + + f->get_buffer(w.ptr(),len); + + memdelete(f); + + Ref ogg_stream; + ogg_stream.instance(); + + ogg_stream->set_data(data); + ogg_stream->set_loop(loop); + + return ResourceSaver::save(p_save_path+".asogg",ogg_stream); +} + +ResourceImporterOGGVorbis::ResourceImporterOGGVorbis() +{ + +} diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.h b/modules/stb_vorbis/resource_importer_ogg_vorbis.h new file mode 100644 index 00000000000..8a3b2d8ec60 --- /dev/null +++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.h @@ -0,0 +1,28 @@ +#ifndef RESOURCEIMPORTEROGGVORBIS_H +#define RESOURCEIMPORTEROGGVORBIS_H + + +#include "io/resource_import.h" +#include "audio_stream_ogg_vorbis.h" + +class ResourceImporterOGGVorbis : public ResourceImporter { + GDCLASS(ResourceImporterOGGVorbis,ResourceImporter) +public: + virtual String get_importer_name() const; + virtual String get_visible_name() const; + virtual void get_recognized_extensions(List *p_extensions) const; + virtual String get_save_extension() const; + virtual String get_resource_type() const; + + virtual int get_preset_count() const; + virtual String get_preset_name(int p_idx) const; + + virtual void get_import_options(List *r_options,int p_preset=0) const; + virtual bool get_option_visibility(const String& p_option,const Map& p_options) const; + + virtual Error import(const String& p_source_file,const String& p_save_path,const Map& p_options,List* r_platform_variants,List* r_gen_files=NULL); + + ResourceImporterOGGVorbis(); +}; + +#endif // RESOURCEIMPORTEROGGVORBIS_H