Changed OGG Vorbis type to be imported, so it's possible to specify loop
This commit is contained in:
parent
9ce2ab9749
commit
d2b2d6801f
|
@ -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<uint8_t>& 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<uint8_t>::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<char>::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<uint8_t> AudioStreamOGGVorbis::get_data() const {
|
||||
|
||||
PoolVector<uint8_t> vdata;
|
||||
|
||||
if (data_len && data) {
|
||||
vdata.resize(data_len);
|
||||
{
|
||||
PoolVector<uint8_t>::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<uint8_t> data;
|
||||
data.resize(len);
|
||||
PoolVector<uint8_t>::Write w = data.write();
|
||||
|
||||
f->get_buffer(w.ptr(),len);
|
||||
|
||||
memdelete(f);
|
||||
|
||||
Ref<AudioStreamOGGVorbis> 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<String> *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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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<AudioStreamPlayback> 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<uint8_t>& p_data);
|
||||
PoolVector<uint8_t> 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<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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<ResourceImporterOGGVorbis> ogg_import;
|
||||
ogg_import.instance();
|
||||
ResourceFormatImporter::get_singleton()->add_importer(ogg_import);
|
||||
#endif
|
||||
ClassDB::register_class<AudioStreamOGGVorbis>();
|
||||
}
|
||||
|
||||
void unregister_stb_vorbis_types() {
|
||||
|
||||
memdelete( vorbis_stream_loader );
|
||||
}
|
||||
|
|
|
@ -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<String> *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<StringName,Variant>& 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<ImportOption> *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<StringName,Variant>& p_options, List<String>* r_platform_variants, List<String> *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<uint8_t> data;
|
||||
data.resize(len);
|
||||
PoolVector<uint8_t>::Write w = data.write();
|
||||
|
||||
f->get_buffer(w.ptr(),len);
|
||||
|
||||
memdelete(f);
|
||||
|
||||
Ref<AudioStreamOGGVorbis> 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()
|
||||
{
|
||||
|
||||
}
|
|
@ -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<String> *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<ImportOption> *r_options,int p_preset=0) const;
|
||||
virtual bool get_option_visibility(const String& p_option,const Map<StringName,Variant>& p_options) const;
|
||||
|
||||
virtual Error import(const String& p_source_file,const String& p_save_path,const Map<StringName,Variant>& p_options,List<String>* r_platform_variants,List<String>* r_gen_files=NULL);
|
||||
|
||||
ResourceImporterOGGVorbis();
|
||||
};
|
||||
|
||||
#endif // RESOURCEIMPORTEROGGVORBIS_H
|
Loading…
Reference in New Issue