diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mpc/audio_stream_mpc.cpp | 128 | ||||
-rw-r--r-- | drivers/mpc/audio_stream_mpc.h | 45 | ||||
-rw-r--r-- | drivers/speex/audio_stream_speex.cpp | 174 | ||||
-rw-r--r-- | drivers/speex/audio_stream_speex.h | 55 | ||||
-rw-r--r-- | drivers/unix/os_unix.cpp | 3 | ||||
-rw-r--r-- | drivers/vorbis/audio_stream_ogg_vorbis.cpp | 206 | ||||
-rw-r--r-- | drivers/vorbis/audio_stream_ogg_vorbis.h | 51 |
7 files changed, 373 insertions, 289 deletions
diff --git a/drivers/mpc/audio_stream_mpc.cpp b/drivers/mpc/audio_stream_mpc.cpp index 67f21f922c..fe6aa05d00 100644 --- a/drivers/mpc/audio_stream_mpc.cpp +++ b/drivers/mpc/audio_stream_mpc.cpp @@ -1,7 +1,7 @@ #include "audio_stream_mpc.h" -Error AudioStreamMPC::_open_file() { +Error AudioStreamPlaybackMPC::_open_file() { if (f) { memdelete(f); @@ -41,7 +41,7 @@ Error AudioStreamMPC::_open_file() { return OK; } -void AudioStreamMPC::_close_file() { +void AudioStreamPlaybackMPC::_close_file() { if (f) { memdelete(f); @@ -52,7 +52,7 @@ void AudioStreamMPC::_close_file() { data_ofs=0; } -int AudioStreamMPC::_read_file(void *p_dst,int p_bytes) { +int AudioStreamPlaybackMPC::_read_file(void *p_dst,int p_bytes) { if (f) return f->get_buffer((uint8_t*)p_dst,p_bytes); @@ -68,7 +68,7 @@ int AudioStreamMPC::_read_file(void *p_dst,int p_bytes) { return p_bytes; } -bool AudioStreamMPC::_seek_file(int p_pos){ +bool AudioStreamPlaybackMPC::_seek_file(int p_pos){ if (p_pos<0 || p_pos>streamlen) return false; @@ -83,7 +83,7 @@ bool AudioStreamMPC::_seek_file(int p_pos){ return true; } -int AudioStreamMPC::_tell_file() const{ +int AudioStreamPlaybackMPC::_tell_file() const{ if (f) return f->get_pos(); @@ -93,13 +93,13 @@ int AudioStreamMPC::_tell_file() const{ } -int AudioStreamMPC::_sizeof_file() const{ +int AudioStreamPlaybackMPC::_sizeof_file() const{ //print_line("sizeof file, get: "+itos(streamlen)); return streamlen; } -bool AudioStreamMPC::_canseek_file() const{ +bool AudioStreamPlaybackMPC::_canseek_file() const{ //print_line("canseek file, get true"); return true; @@ -107,51 +107,46 @@ bool AudioStreamMPC::_canseek_file() const{ ///////////////////// -mpc_int32_t AudioStreamMPC::_mpc_read(mpc_reader *p_reader,void *p_dst, mpc_int32_t p_bytes) { +mpc_int32_t AudioStreamPlaybackMPC::_mpc_read(mpc_reader *p_reader,void *p_dst, mpc_int32_t p_bytes) { - AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data; + AudioStreamPlaybackMPC *smpc=(AudioStreamPlaybackMPC *)p_reader->data; return smpc->_read_file(p_dst,p_bytes); } -mpc_bool_t AudioStreamMPC::_mpc_seek(mpc_reader *p_reader,mpc_int32_t p_offset) { +mpc_bool_t AudioStreamPlaybackMPC::_mpc_seek(mpc_reader *p_reader,mpc_int32_t p_offset) { - AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data; + AudioStreamPlaybackMPC *smpc=(AudioStreamPlaybackMPC *)p_reader->data; return smpc->_seek_file(p_offset); } -mpc_int32_t AudioStreamMPC::_mpc_tell(mpc_reader *p_reader) { +mpc_int32_t AudioStreamPlaybackMPC::_mpc_tell(mpc_reader *p_reader) { - AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data; + AudioStreamPlaybackMPC *smpc=(AudioStreamPlaybackMPC *)p_reader->data; return smpc->_tell_file(); } -mpc_int32_t AudioStreamMPC::_mpc_get_size(mpc_reader *p_reader) { +mpc_int32_t AudioStreamPlaybackMPC::_mpc_get_size(mpc_reader *p_reader) { - AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data; + AudioStreamPlaybackMPC *smpc=(AudioStreamPlaybackMPC *)p_reader->data; return smpc->_sizeof_file(); } -mpc_bool_t AudioStreamMPC::_mpc_canseek(mpc_reader *p_reader) { +mpc_bool_t AudioStreamPlaybackMPC::_mpc_canseek(mpc_reader *p_reader) { - AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data; + AudioStreamPlaybackMPC *smpc=(AudioStreamPlaybackMPC *)p_reader->data; return smpc->_canseek_file(); } -bool AudioStreamMPC::_can_mix() const { - return /*active &&*/ !paused; -} - - -void AudioStreamMPC::update() { +int AudioStreamPlaybackMPC::mix(int16_t* p_bufer,int p_frames) { if (!active || paused) - return; + return 0; - int todo=get_todo(); + int todo=p_frames; while(todo>MPC_DECODER_BUFFER_LENGTH/si.channels) { @@ -162,7 +157,7 @@ void AudioStreamMPC::update() { mpc_status err = mpc_demux_decode(demux, &frame); if (frame.bits!=-1) { - int16_t *dst_buff = get_write_buffer(); + int16_t *dst_buff = p_bufer; #ifdef MPC_FIXED_POINT @@ -185,21 +180,21 @@ void AudioStreamMPC::update() { #endif int frames = frame.samples; - write(frames); + p_bufer+=si.channels*frames; todo-=frames; } else { if (err != MPC_STATUS_OK) { stop(); - ERR_EXPLAIN("Error decoding MPC"); - ERR_FAIL(); + ERR_PRINT("Error decoding MPC"); + break; } else { //finished if (!loop) { stop(); - return; + break; } else { @@ -213,9 +208,11 @@ void AudioStreamMPC::update() { } } } + + return p_frames-todo; } -Error AudioStreamMPC::_reload() { +Error AudioStreamPlaybackMPC::_reload() { ERR_FAIL_COND_V(demux!=NULL, ERR_FILE_ALREADY_IN_USE); @@ -224,31 +221,40 @@ Error AudioStreamMPC::_reload() { demux = mpc_demux_init(&reader); ERR_FAIL_COND_V(!demux,ERR_CANT_CREATE); - mpc_demux_get_info(demux, &si); - _setup(si.channels,si.sample_freq,MPC_DECODER_BUFFER_LENGTH*2/si.channels); return OK; } -void AudioStreamMPC::set_file(const String& p_file) { +void AudioStreamPlaybackMPC::set_file(const String& p_file) { file=p_file; + Error err = _open_file(); + ERR_FAIL_COND(err!=OK); + demux = mpc_demux_init(&reader); + ERR_FAIL_COND(!demux); + mpc_demux_get_info(demux, &si); + stream_min_size=MPC_DECODER_BUFFER_LENGTH*2/si.channels; + stream_rate=si.sample_freq; + stream_channels=si.channels; + + mpc_demux_exit(demux); + demux=NULL; + _close_file(); + } -String AudioStreamMPC::get_file() const { +String AudioStreamPlaybackMPC::get_file() const { return file; } -void AudioStreamMPC::play() { +void AudioStreamPlaybackMPC::play(float p_offset) { - _THREAD_SAFE_METHOD_ - if (active) stop(); active=false; @@ -262,9 +268,9 @@ void AudioStreamMPC::play() { } -void AudioStreamMPC::stop() { +void AudioStreamPlaybackMPC::stop() { + - _THREAD_SAFE_METHOD_ if (!active) return; if (demux) { @@ -275,70 +281,58 @@ void AudioStreamMPC::stop() { active=false; } -bool AudioStreamMPC::is_playing() const { +bool AudioStreamPlaybackMPC::is_playing() const { - return active || (get_total() - get_todo() -1 > 0); + return active; } -void AudioStreamMPC::set_paused(bool p_paused) { - paused=p_paused; -} -bool AudioStreamMPC::is_paused(bool p_paused) const { - - return paused; -} - -void AudioStreamMPC::set_loop(bool p_enable) { +void AudioStreamPlaybackMPC::set_loop(bool p_enable) { loop=p_enable; } -bool AudioStreamMPC::has_loop() const { +bool AudioStreamPlaybackMPC::has_loop() const { return loop; } -float AudioStreamMPC::get_length() const { +float AudioStreamPlaybackMPC::get_length() const { return 0; } -String AudioStreamMPC::get_stream_name() const { +String AudioStreamPlaybackMPC::get_stream_name() const { return ""; } -int AudioStreamMPC::get_loop_count() const { +int AudioStreamPlaybackMPC::get_loop_count() const { return 0; } -float AudioStreamMPC::get_pos() const { +float AudioStreamPlaybackMPC::get_pos() const { return 0; } -void AudioStreamMPC::seek_pos(float p_time) { +void AudioStreamPlaybackMPC::seek_pos(float p_time) { } -AudioStream::UpdateMode AudioStreamMPC::get_update_mode() const { - - return UPDATE_THREAD; -} -void AudioStreamMPC::_bind_methods() { +void AudioStreamPlaybackMPC::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_file","name"),&AudioStreamMPC::set_file); - ObjectTypeDB::bind_method(_MD("get_file"),&AudioStreamMPC::get_file); + ObjectTypeDB::bind_method(_MD("set_file","name"),&AudioStreamPlaybackMPC::set_file); + ObjectTypeDB::bind_method(_MD("get_file"),&AudioStreamPlaybackMPC::get_file); ADD_PROPERTYNZ( PropertyInfo(Variant::STRING,"file",PROPERTY_HINT_FILE,"mpc"), _SCS("set_file"), _SCS("get_file")); } -AudioStreamMPC::AudioStreamMPC() { +AudioStreamPlaybackMPC::AudioStreamPlaybackMPC() { - preload=true; + preload=false; f=NULL; streamlen=0; data_ofs=0; @@ -356,7 +350,7 @@ AudioStreamMPC::AudioStreamMPC() { } -AudioStreamMPC::~AudioStreamMPC() { +AudioStreamPlaybackMPC::~AudioStreamPlaybackMPC() { stop(); diff --git a/drivers/mpc/audio_stream_mpc.h b/drivers/mpc/audio_stream_mpc.h index 8fb0ed13de..122d0d0bbb 100644 --- a/drivers/mpc/audio_stream_mpc.h +++ b/drivers/mpc/audio_stream_mpc.h @@ -1,18 +1,17 @@ #ifndef AUDIO_STREAM_MPC_H #define AUDIO_STREAM_MPC_H -#include "scene/resources/audio_stream_resampled.h" +#include "scene/resources/audio_stream.h" #include "os/file_access.h" #include "mpc/mpcdec.h" #include "os/thread_safe.h" #include "io/resource_loader.h" //#include "../libmpcdec/decoder.h" //#include "../libmpcdec/internal.h" -class AudioStreamMPC : public AudioStreamResampled { - OBJ_TYPE( AudioStreamMPC, AudioStreamResampled ); +class AudioStreamPlaybackMPC : public AudioStreamPlayback { - _THREAD_SAFE_CLASS_ + OBJ_TYPE( AudioStreamPlaybackMPC, AudioStreamPlayback ); bool preload; FileAccess *f; @@ -39,7 +38,9 @@ class AudioStreamMPC : public AudioStreamResampled { static mpc_int32_t _mpc_get_size(mpc_reader *p_reader); static mpc_bool_t _mpc_canseek(mpc_reader *p_reader); - virtual bool _can_mix() const ; + int stream_min_size; + int stream_rate; + int stream_channels; protected: Error _open_file(); @@ -59,12 +60,10 @@ public: void set_file(const String& p_file); String get_file() const; - virtual void play(); + virtual void play(float p_offset=0); virtual void stop(); virtual bool is_playing() const; - virtual void set_paused(bool p_paused); - virtual bool is_paused(bool p_paused) const; virtual void set_loop(bool p_enable); virtual bool has_loop() const; @@ -78,13 +77,35 @@ public: virtual float get_pos() const; virtual void seek_pos(float p_time); - virtual UpdateMode get_update_mode() const; - virtual void update(); + virtual int get_channels() const { return stream_channels; } + virtual int get_mix_rate() const { return stream_rate; } - AudioStreamMPC(); - ~AudioStreamMPC(); + virtual int get_minimum_buffer_size() const { return stream_min_size; } + virtual int mix(int16_t* p_bufer,int p_frames); + + virtual void set_loop_restart_time(float p_time) { } + + AudioStreamPlaybackMPC(); + ~AudioStreamPlaybackMPC(); }; +class AudioStreamMPC : public AudioStream { + + OBJ_TYPE( AudioStreamMPC, AudioStream ); + + String file; +public: + + Ref<AudioStreamPlayback> instance_playback() { + Ref<AudioStreamPlaybackMPC> pb = memnew( AudioStreamPlaybackMPC ); + pb->set_file(file); + return pb; + } + + void set_file(const String& p_file) { file=p_file; } + + +}; class ResourceFormatLoaderAudioStreamMPC : public ResourceFormatLoader { public: diff --git a/drivers/speex/audio_stream_speex.cpp b/drivers/speex/audio_stream_speex.cpp index 2cffb17049..2440969345 100644 --- a/drivers/speex/audio_stream_speex.cpp +++ b/drivers/speex/audio_stream_speex.cpp @@ -15,14 +15,15 @@ static _FORCE_INLINE_ uint16_t le_short(uint16_t s) } -void AudioStreamSpeex::update() { +int AudioStreamPlaybackSpeex::mix(int16_t* p_buffer,int p_frames) { + + - _THREAD_SAFE_METHOD_; //printf("update, loops %i, read ofs %i\n", (int)loops, read_ofs); //printf("playing %i, paused %i\n", (int)playing, (int)paused); if (!active || !playing || paused || !data.size()) - return; + return 0; /* if (read_ofs >= data.size()) { @@ -35,12 +36,13 @@ void AudioStreamSpeex::update() { }; */ - int todo = get_todo(); + int todo = p_frames; if (todo < page_size) { - return; + return 0; }; - int eos = 0; + int eos = 0; + bool reloaded=false; while (todo > page_size) { @@ -92,7 +94,7 @@ void AudioStreamSpeex::update() { for (int j=0;j!=nframes;j++) { - int16_t* out = get_write_buffer(); + int16_t* out = p_buffer; int ret; /*Decode frame*/ @@ -120,7 +122,7 @@ void AudioStreamSpeex::update() { /*Convert to short and save to output file*/ - for (int i=0;i<frame_size*get_channel_count();i++) { + for (int i=0;i<frame_size*stream_channels;i++) { out[i]=le_short(out[i]); } @@ -149,7 +151,7 @@ void AudioStreamSpeex::update() { } - write(new_frame_size); + p_buffer+=new_frame_size*stream_channels; todo-=new_frame_size; } } @@ -175,6 +177,7 @@ void AudioStreamSpeex::update() { if (loops) { reload(); ++loop_count; + //break; } else { playing=false; unload(); @@ -183,18 +186,22 @@ void AudioStreamSpeex::update() { } }; }; + + return p_frames-todo; }; -void AudioStreamSpeex::unload() { +void AudioStreamPlaybackSpeex::unload() { + - _THREAD_SAFE_METHOD_ if (!active) return; speex_bits_destroy(&bits); if (st) speex_decoder_destroy(st); + + ogg_sync_clear(&oy); active = false; //data.resize(0); st = NULL; @@ -204,7 +211,7 @@ void AudioStreamSpeex::unload() { loop_count = 0; } -void *AudioStreamSpeex::process_header(ogg_packet *op, int *frame_size, int *rate, int *nframes, int *channels, int *extra_headers) { +void *AudioStreamPlaybackSpeex::process_header(ogg_packet *op, int *frame_size, int *rate, int *nframes, int *channels, int *extra_headers) { void *st; SpeexHeader *header; @@ -276,9 +283,9 @@ void *AudioStreamSpeex::process_header(ogg_packet *op, int *frame_size, int *rat -void AudioStreamSpeex::reload() { +void AudioStreamPlaybackSpeex::reload() { + - _THREAD_SAFE_METHOD_ if (active) unload(); @@ -359,8 +366,10 @@ void AudioStreamSpeex::reload() { }; page_size = nframes * frame_size; + stream_srate=rate; + stream_channels=channels; + stream_minbuff_size=page_size; - _setup(channels, rate,page_size); } else if (packet_count==1) { @@ -374,23 +383,23 @@ void AudioStreamSpeex::reload() { } while (packet_count <= extra_headers); - active = true; + active=true; } -void AudioStreamSpeex::_bind_methods() { +void AudioStreamPlaybackSpeex::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_file","file"),&AudioStreamSpeex::set_file); - ObjectTypeDB::bind_method(_MD("get_file"),&AudioStreamSpeex::get_file); + //ObjectTypeDB::bind_method(_MD("set_file","file"),&AudioStreamPlaybackSpeex::set_file); +// ObjectTypeDB::bind_method(_MD("get_file"),&AudioStreamPlaybackSpeex::get_file); - ObjectTypeDB::bind_method(_MD("_set_bundled"),&AudioStreamSpeex::_set_bundled); - ObjectTypeDB::bind_method(_MD("_get_bundled"),&AudioStreamSpeex::_get_bundled); + ObjectTypeDB::bind_method(_MD("_set_bundled"),&AudioStreamPlaybackSpeex::_set_bundled); + ObjectTypeDB::bind_method(_MD("_get_bundled"),&AudioStreamPlaybackSpeex::_get_bundled); ADD_PROPERTY( PropertyInfo(Variant::DICTIONARY,"_bundled",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_BUNDLE),_SCS("_set_bundled"),_SCS("_get_bundled")); - ADD_PROPERTY( PropertyInfo(Variant::STRING,"file",PROPERTY_HINT_FILE,"*.spx"),_SCS("set_file"),_SCS("get_file")); + //ADD_PROPERTY( PropertyInfo(Variant::STRING,"file",PROPERTY_HINT_FILE,"*.spx"),_SCS("set_file"),_SCS("get_file")); }; -void AudioStreamSpeex::_set_bundled(const Dictionary& dict) { +void AudioStreamPlaybackSpeex::_set_bundled(const Dictionary& dict) { ERR_FAIL_COND( !dict.has("filename")); ERR_FAIL_COND( !dict.has("data")); @@ -399,7 +408,7 @@ void AudioStreamSpeex::_set_bundled(const Dictionary& dict) { data = dict["data"]; }; -Dictionary AudioStreamSpeex::_get_bundled() const { +Dictionary AudioStreamPlaybackSpeex::_get_bundled() const { Dictionary d; d["filename"] = filename; @@ -408,43 +417,17 @@ Dictionary AudioStreamSpeex::_get_bundled() const { }; -String AudioStreamSpeex::get_file() const { - - return filename; -}; - -void AudioStreamSpeex::set_file(const String& p_file){ - - if (filename == p_file) - return; - - if (active) { - unload(); - } - - if (p_file == "") { - data.resize(0); - return; - }; - - Error err; - FileAccess* file = FileAccess::open(p_file, FileAccess::READ,&err); - if (err != OK) { - data.resize(0); - }; - ERR_FAIL_COND(err != OK); - filename = p_file; - data.resize(file->get_len()); - int read = file->get_buffer(&data[0], data.size()); - memdelete(file); +void AudioStreamPlaybackSpeex::set_data(const Vector<uint8_t>& p_data) { + data=p_data; reload(); } -void AudioStreamSpeex::play() { - _THREAD_SAFE_METHOD_ +void AudioStreamPlaybackSpeex::play(float p_from_pos) { + + reload(); if (!active) @@ -452,82 +435,101 @@ void AudioStreamSpeex::play() { playing = true; } -void AudioStreamSpeex::stop(){ +void AudioStreamPlaybackSpeex::stop(){ + - _THREAD_SAFE_METHOD_ unload(); playing = false; - _clear(); -} -bool AudioStreamSpeex::is_playing() const{ - return _is_ready() && (playing || (get_total() - get_todo() -1 > 0)); } +bool AudioStreamPlaybackSpeex::is_playing() const{ -void AudioStreamSpeex::set_paused(bool p_paused){ - - playing = !p_paused; - paused = p_paused; + return playing; } -bool AudioStreamSpeex::is_paused(bool p_paused) const{ - return paused; -} -void AudioStreamSpeex::set_loop(bool p_enable){ +void AudioStreamPlaybackSpeex::set_loop(bool p_enable){ loops = p_enable; } -bool AudioStreamSpeex::has_loop() const{ +bool AudioStreamPlaybackSpeex::has_loop() const{ return loops; } -float AudioStreamSpeex::get_length() const{ +float AudioStreamPlaybackSpeex::get_length() const{ return 0; } -String AudioStreamSpeex::get_stream_name() const{ +String AudioStreamPlaybackSpeex::get_stream_name() const{ return ""; } -int AudioStreamSpeex::get_loop_count() const{ +int AudioStreamPlaybackSpeex::get_loop_count() const{ return 0; } -float AudioStreamSpeex::get_pos() const{ +float AudioStreamPlaybackSpeex::get_pos() const{ return 0; } -void AudioStreamSpeex::seek_pos(float p_time){ +void AudioStreamPlaybackSpeex::seek_pos(float p_time){ }; -bool AudioStreamSpeex::_can_mix() const { - //return playing; - return data.size() != 0; -}; +AudioStreamPlaybackSpeex::AudioStreamPlaybackSpeex() { -AudioStream::UpdateMode AudioStreamSpeex::get_update_mode() const { + active=false; + st = NULL; + stream_channels=1; + stream_srate=1; + stream_minbuff_size=1; - return UPDATE_THREAD; } -AudioStreamSpeex::AudioStreamSpeex() { +AudioStreamPlaybackSpeex::~AudioStreamPlaybackSpeex() { - active=false; - st = NULL; + unload(); } -AudioStreamSpeex::~AudioStreamSpeex() { - unload(); + + + +//////////////////////////////////////// + + + +void AudioStreamSpeex::set_file(const String& p_file) { + + if (this->file == p_file) + return; + + this->file=p_file; + + if (p_file == "") { + data.resize(0); + return; + }; + + Error err; + FileAccess* file = FileAccess::open(p_file, FileAccess::READ,&err); + if (err != OK) { + data.resize(0); + }; + ERR_FAIL_COND(err != OK); + + this->file = p_file; + data.resize(file->get_len()); + int read = file->get_buffer(&data[0], data.size()); + memdelete(file); + } RES ResourceFormatLoaderAudioStreamSpeex::load(const String &p_path, const String& p_original_path, Error *r_error) { diff --git a/drivers/speex/audio_stream_speex.h b/drivers/speex/audio_stream_speex.h index f9e0fce666..570e846734 100644 --- a/drivers/speex/audio_stream_speex.h +++ b/drivers/speex/audio_stream_speex.h @@ -1,7 +1,7 @@ #ifndef AUDIO_STREAM_SPEEX_H #define AUDIO_STREAM_SPEEX_H -#include "scene/resources/audio_stream_resampled.h" +#include "scene/resources/audio_stream.h" #include "speex/speex.h" #include "os/file_access.h" #include "io/resource_loader.h" @@ -14,10 +14,10 @@ #include <ogg/ogg.h> -class AudioStreamSpeex : public AudioStreamResampled { +class AudioStreamPlaybackSpeex : public AudioStreamPlayback { + + OBJ_TYPE(AudioStreamPlaybackSpeex, AudioStreamPlayback); - OBJ_TYPE(AudioStreamSpeex, AudioStreamResampled); - _THREAD_SAFE_CLASS_ void *st; SpeexBits bits; @@ -45,6 +45,9 @@ class AudioStreamSpeex : public AudioStreamResampled { ogg_int64_t page_granule, last_granule; int skip_samples, page_nb_packets; + int stream_channels; + int stream_srate; + int stream_minbuff_size; void* process_header(ogg_packet *op, int *frame_size, int *rate, int *nframes, int *channels, int *extra_headers); @@ -52,7 +55,7 @@ class AudioStreamSpeex : public AudioStreamResampled { protected: - virtual bool _can_mix() const; + //virtual bool _can_mix() const; Dictionary _get_bundled() const; void _set_bundled(const Dictionary& dict); @@ -60,16 +63,12 @@ protected: public: - void set_file(const String& p_file); - String get_file() const; + void set_data(const Vector<uint8_t>& p_data); - virtual void play(); + virtual void play(float p_from_pos=0); virtual void stop(); virtual bool is_playing() const; - virtual void set_paused(bool p_paused); - virtual bool is_paused(bool p_paused) const; - virtual void set_loop(bool p_enable); virtual bool has_loop() const; @@ -82,13 +81,39 @@ public: virtual float get_pos() const; virtual void seek_pos(float p_time); - virtual UpdateMode get_update_mode() const; - virtual void update(); + virtual int get_channels() const { return stream_channels; } + virtual int get_mix_rate() const { return stream_srate; } + + virtual int get_minimum_buffer_size() const { return stream_minbuff_size; } + virtual int mix(int16_t* p_bufer,int p_frames); + + virtual void set_loop_restart_time(float p_time) { } //no loop restart, ignore + + AudioStreamPlaybackSpeex(); + ~AudioStreamPlaybackSpeex(); +}; + + + +class AudioStreamSpeex : public AudioStream { + + OBJ_TYPE(AudioStreamSpeex,AudioStream); + + Vector<uint8_t> data; + String file; +public: + + Ref<AudioStreamPlayback> instance_playback() { + Ref<AudioStreamPlaybackSpeex> pb = memnew( AudioStreamPlaybackSpeex ); + pb->set_data(data); + return pb; + } + + void set_file(const String& p_file); - AudioStreamSpeex(); - ~AudioStreamSpeex(); }; + class ResourceFormatLoaderAudioStreamSpeex : public ResourceFormatLoader { public: virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL); diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 314e13cee4..05af7ee900 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -226,7 +226,8 @@ uint64_t OS_Unix::get_unix_time() const { uint64_t OS_Unix::get_system_time_msec() const { struct timeval tv_now; gettimeofday(&tv_now, NULL); - localtime(&tv_now.tv_usec); + //localtime(&tv_now.tv_usec); + localtime((const long *)&tv_now.tv_usec); uint64_t msec = tv_now.tv_usec/1000; return msec; } diff --git a/drivers/vorbis/audio_stream_ogg_vorbis.cpp b/drivers/vorbis/audio_stream_ogg_vorbis.cpp index ee9ba8da4d..ca055c8b62 100644 --- a/drivers/vorbis/audio_stream_ogg_vorbis.cpp +++ b/drivers/vorbis/audio_stream_ogg_vorbis.cpp @@ -30,7 +30,7 @@ -size_t AudioStreamOGGVorbis::_ov_read_func(void *p_dst,size_t p_data, size_t p_count, void *_f) { +size_t AudioStreamPlaybackOGGVorbis::_ov_read_func(void *p_dst,size_t p_data, size_t p_count, void *_f) { //printf("read to %p, %i bytes, %i nmemb, %p\n",p_dst,p_data,p_count,_f); FileAccess *fa=(FileAccess*)_f; @@ -46,7 +46,7 @@ size_t AudioStreamOGGVorbis::_ov_read_func(void *p_dst,size_t p_data, size_t p_c return read; } -int AudioStreamOGGVorbis::_ov_seek_func(void *_f,ogg_int64_t offs, int whence) { +int AudioStreamPlaybackOGGVorbis::_ov_seek_func(void *_f,ogg_int64_t offs, int whence) { //printf("seek to %p, offs %i, whence %i\n",_f,(int)offs,whence); @@ -76,7 +76,7 @@ int AudioStreamOGGVorbis::_ov_seek_func(void *_f,ogg_int64_t offs, int whence) { #endif } -int AudioStreamOGGVorbis::_ov_close_func(void *_f) { +int AudioStreamPlaybackOGGVorbis::_ov_close_func(void *_f) { // printf("close %p\n",_f); if (!_f) @@ -86,7 +86,7 @@ int AudioStreamOGGVorbis::_ov_close_func(void *_f) { fa->close(); return 0; } -long AudioStreamOGGVorbis::_ov_tell_func(void *_f) { +long AudioStreamPlaybackOGGVorbis::_ov_tell_func(void *_f) { //printf("close %p\n",_f); @@ -95,38 +95,32 @@ long AudioStreamOGGVorbis::_ov_tell_func(void *_f) { } -bool AudioStreamOGGVorbis::_can_mix() const { - return /*playing &&*/ !paused; -} - - -void AudioStreamOGGVorbis::update() { +int AudioStreamPlaybackOGGVorbis::mix(int16_t* p_bufer,int p_frames) { - _THREAD_SAFE_METHOD_ - - if (!playing && !setting_up) - return; + if (!playing) + return 0; + int total=p_frames; while (true) { - int todo = get_todo(); + int todo = p_frames; - if (todo==0 || todo<MIN_MIX) + if (todo==0 || todo<MIN_MIX) { break; + } //printf("to mix %i - mix me %i bytes\n",to_mix,to_mix*stream_channels*sizeof(int16_t)); #ifdef BIG_ENDIAN_ENABLED - long ret=ov_read(&vf,(char*)get_write_buffer(),todo*stream_channels*sizeof(int16_t), 1, 2, 1, ¤t_section); + long ret=ov_read(&vf,(char*)p_bufer,todo*stream_channels*sizeof(int16_t), 1, 2, 1, ¤t_section); #else - long ret=ov_read(&vf,(char*)get_write_buffer(),todo*stream_channels*sizeof(int16_t), 0, 2, 1, ¤t_section); + long ret=ov_read(&vf,(char*)p_bufer,todo*stream_channels*sizeof(int16_t), 0, 2, 1, ¤t_section); #endif + if (ret<0) { playing = false; - setting_up=false; - ERR_EXPLAIN("Error reading OGG Vorbis File: "+file); ERR_BREAK(ret<0); } else if (ret==0) { // end of song, reload? @@ -138,9 +132,8 @@ void AudioStreamOGGVorbis::update() { if (!has_loop()) { playing=false; - setting_up=false; repeats=1; - return; + break; } f=FileAccess::open(file,FileAccess::READ); @@ -148,11 +141,22 @@ void AudioStreamOGGVorbis::update() { int errv = ov_open_callbacks(f,&vf,NULL,0,_ov_callbacks); if (errv!=0) { playing=false; - setting_up=false; - return; // :( + break;; // :( } - frames_mixed=0; + if (loop_restart_time) { + bool ok = ov_time_seek(&vf,loop_restart_time)==0; + if (!ok) { + playing=false; + //ERR_EXPLAIN("loop restart time rejected"); + ERR_PRINT("loop restart time rejected") + } + + frames_mixed=stream_srate*loop_restart_time; + } else { + + frames_mixed=0; + } repeats++; continue; @@ -162,16 +166,19 @@ void AudioStreamOGGVorbis::update() { ret/=sizeof(int16_t); frames_mixed+=ret; - write(ret); + + p_bufer+=ret*stream_channels; + p_frames-=ret; + } -} + return total-p_frames; +} -void AudioStreamOGGVorbis::play() { - _THREAD_SAFE_METHOD_ +void AudioStreamPlaybackOGGVorbis::play(float p_from) { if (playing) stop(); @@ -179,56 +186,46 @@ void AudioStreamOGGVorbis::play() { if (_load_stream()!=OK) return; + frames_mixed=0; - playing=false; - setting_up=true; - update(); - if (!setting_up) - return; - setting_up=false; playing=true; + if (p_from>0) { + seek_pos(p_from); + } } -void AudioStreamOGGVorbis::_close_file() { +void AudioStreamPlaybackOGGVorbis::_close_file() { if (f) { + memdelete(f); f=NULL; } } -void AudioStreamOGGVorbis::stop() { - - _THREAD_SAFE_METHOD_ +bool AudioStreamPlaybackOGGVorbis::is_playing() const { + return playing; +} +void AudioStreamPlaybackOGGVorbis::stop() { _clear_stream(); playing=false; - _clear(); -} - -AudioStreamOGGVorbis::UpdateMode AudioStreamOGGVorbis::get_update_mode() const { - - return UPDATE_THREAD; + //_clear(); } -bool AudioStreamOGGVorbis::is_playing() const { +float AudioStreamPlaybackOGGVorbis::get_pos() const { - return playing || (get_total() - get_todo() -1 > 0); -} - -float AudioStreamOGGVorbis::get_pos() const { - - int32_t frames = int32_t(frames_mixed) - (int32_t(get_total()) - get_todo()); + int32_t frames = int32_t(frames_mixed); if (frames < 0) frames=0; return double(frames) / stream_srate; } -void AudioStreamOGGVorbis::seek_pos(float p_time) { +void AudioStreamPlaybackOGGVorbis::seek_pos(float p_time) { + - _THREAD_SAFE_METHOD_ if (!playing) return; @@ -237,85 +234,107 @@ void AudioStreamOGGVorbis::seek_pos(float p_time) { frames_mixed=stream_srate*p_time; } -String AudioStreamOGGVorbis::get_stream_name() const { +String AudioStreamPlaybackOGGVorbis::get_stream_name() const { return ""; } -void AudioStreamOGGVorbis::set_loop(bool p_enable) { +void AudioStreamPlaybackOGGVorbis::set_loop(bool p_enable) { loops=p_enable; } -bool AudioStreamOGGVorbis::has_loop() const { +bool AudioStreamPlaybackOGGVorbis::has_loop() const { return loops; } -int AudioStreamOGGVorbis::get_loop_count() const { +int AudioStreamPlaybackOGGVorbis::get_loop_count() const { return repeats; } -void AudioStreamOGGVorbis::set_file(const String& p_file) { +Error AudioStreamPlaybackOGGVorbis::set_file(const String& p_file) { file=p_file; -} - -Error AudioStreamOGGVorbis::_load_stream() { - - _clear_stream(); - if (file=="") - return ERR_INVALID_DATA; - + stream_valid=false; Error err; f=FileAccess::open(file,FileAccess::READ,&err); - if (err) { ERR_FAIL_COND_V( err, err ); } int errv = ov_open_callbacks(f,&vf,NULL,0,_ov_callbacks); + switch(errv) { - + case OV_EREAD: { // - A read from media returned an error. + memdelete(f); f=NULL; + ERR_FAIL_V( ERR_FILE_CANT_READ ); + } break; + case OV_EVERSION: // - Vorbis version mismatch. + case OV_ENOTVORBIS: { // - Bitstream is not Vorbis data. + memdelete(f); f=NULL; + ERR_FAIL_V( ERR_FILE_UNRECOGNIZED ); + } break; + case OV_EBADHEADER: { // - Invalid Vorbis bitstream header. + memdelete(f); f=NULL; + ERR_FAIL_V( ERR_FILE_CORRUPT ); + } break; + case OV_EFAULT: { // - Internal logic fault; indicates a bug or heap/stack corruption. + memdelete(f); f=NULL; + ERR_FAIL_V( ERR_BUG ); + } break; + } const vorbis_info *vinfo=ov_info(&vf,-1); stream_channels=vinfo->channels; stream_srate=vinfo->rate; - Error serr = _setup(stream_channels,stream_srate); + ogg_int64_t len = ov_time_total(&vf,-1); + length=len/1000.0; + ov_clear(&vf); + memdelete(f); + f=NULL; + stream_valid=true; + + + return OK; +} + +Error AudioStreamPlaybackOGGVorbis::_load_stream() { + + ERR_FAIL_COND_V(!stream_valid,ERR_UNCONFIGURED); - if (serr) { - _close_file(); - ERR_FAIL_V( ERR_INVALID_DATA ); + _clear_stream(); + if (file=="") + return ERR_INVALID_DATA; + + Error err; + f=FileAccess::open(file,FileAccess::READ,&err); + if (err) { + ERR_FAIL_COND_V( err, err ); } + int errv = ov_open_callbacks(f,&vf,NULL,0,_ov_callbacks); switch(errv) { case OV_EREAD: { // - A read from media returned an error. - _close_file(); + memdelete(f); f=NULL; ERR_FAIL_V( ERR_FILE_CANT_READ ); } break; case OV_EVERSION: // - Vorbis version mismatch. case OV_ENOTVORBIS: { // - Bitstream is not Vorbis data. - _close_file(); + memdelete(f); f=NULL; ERR_FAIL_V( ERR_FILE_UNRECOGNIZED ); } break; case OV_EBADHEADER: { // - Invalid Vorbis bitstream header. - _close_file(); + memdelete(f); f=NULL; ERR_FAIL_V( ERR_FILE_CORRUPT ); } break; case OV_EFAULT: { // - Internal logic fault; indicates a bug or heap/stack corruption. - - _close_file(); + memdelete(f); f=NULL; ERR_FAIL_V( ERR_BUG ); } break; } - - - ogg_int64_t len = ov_time_total(&vf,-1); - - length=len/1000.0; - repeats=0; stream_loaded=true; @@ -324,16 +343,16 @@ Error AudioStreamOGGVorbis::_load_stream() { } -float AudioStreamOGGVorbis::get_length() const { +float AudioStreamPlaybackOGGVorbis::get_length() const { if (!stream_loaded) { - if (const_cast<AudioStreamOGGVorbis*>(this)->_load_stream()!=OK) + if (const_cast<AudioStreamPlaybackOGGVorbis*>(this)->_load_stream()!=OK) return 0; } return length; } -void AudioStreamOGGVorbis::_clear_stream() { +void AudioStreamPlaybackOGGVorbis::_clear_stream() { if (!stream_loaded) return; @@ -346,18 +365,18 @@ void AudioStreamOGGVorbis::_clear_stream() { playing=false; } -void AudioStreamOGGVorbis::set_paused(bool p_paused) { +void AudioStreamPlaybackOGGVorbis::set_paused(bool p_paused) { paused=p_paused; } -bool AudioStreamOGGVorbis::is_paused(bool p_paused) const { +bool AudioStreamPlaybackOGGVorbis::is_paused(bool p_paused) const { return paused; } -AudioStreamOGGVorbis::AudioStreamOGGVorbis() { +AudioStreamPlaybackOGGVorbis::AudioStreamPlaybackOGGVorbis() { loops=false; playing=false; @@ -367,17 +386,18 @@ AudioStreamOGGVorbis::AudioStreamOGGVorbis() { _ov_callbacks.tell_func=_ov_tell_func; f = NULL; stream_loaded=false; - repeats=0; - setting_up=false; + stream_valid=false; + repeats=0; paused=true; stream_channels=0; stream_srate=0; current_section=0; length=0; + loop_restart_time=0; } -AudioStreamOGGVorbis::~AudioStreamOGGVorbis() { +AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() { _clear_stream(); diff --git a/drivers/vorbis/audio_stream_ogg_vorbis.h b/drivers/vorbis/audio_stream_ogg_vorbis.h index 5e3649d980..827d8b0be3 100644 --- a/drivers/vorbis/audio_stream_ogg_vorbis.h +++ b/drivers/vorbis/audio_stream_ogg_vorbis.h @@ -29,17 +29,16 @@ #ifndef AUDIO_STREAM_OGG_VORBIS_H #define AUDIO_STREAM_OGG_VORBIS_H -#include "scene/resources/audio_stream_resampled.h" +#include "scene/resources/audio_stream.h" #include "vorbis/vorbisfile.h" #include "os/file_access.h" #include "io/resource_loader.h" #include "os/thread_safe.h" -class AudioStreamOGGVorbis : public AudioStreamResampled { - OBJ_TYPE(AudioStreamOGGVorbis,AudioStreamResampled); - _THREAD_SAFE_CLASS_ +class AudioStreamPlaybackOGGVorbis : public AudioStreamPlayback { + OBJ_TYPE(AudioStreamPlaybackOGGVorbis,AudioStreamPlayback); enum { MIN_MIX=1024 @@ -54,9 +53,6 @@ class AudioStreamOGGVorbis : public AudioStreamResampled { static int _ov_close_func(void *_f); static long _ov_tell_func(void *_f); - - virtual bool _can_mix() const; - String file; int64_t frames_mixed; @@ -67,7 +63,7 @@ class AudioStreamOGGVorbis : public AudioStreamResampled { int stream_srate; int current_section; - volatile bool setting_up; + bool paused; bool loops; int repeats; @@ -76,17 +72,21 @@ class AudioStreamOGGVorbis : public AudioStreamResampled { void _clear_stream(); void _close_file(); + bool stream_valid; + float loop_restart_time; -public: +public: - void set_file(const String& p_file); + Error set_file(const String& p_file); - virtual void play(); + virtual void play(float p_from=0); virtual void stop(); virtual bool is_playing() const; + virtual void set_loop_restart_time(float p_time) { loop_restart_time=0; } + virtual void set_paused(bool p_paused); virtual bool is_paused(bool p_paused) const; @@ -102,11 +102,32 @@ public: virtual float get_pos() const; virtual void seek_pos(float p_time); - virtual UpdateMode get_update_mode() const; - virtual void update(); + virtual int get_channels() const { return stream_channels; } + virtual int get_mix_rate() const { return stream_srate; } + + virtual int get_minimum_buffer_size() const { return 0; } + virtual int mix(int16_t* p_bufer,int p_frames); + + AudioStreamPlaybackOGGVorbis(); + ~AudioStreamPlaybackOGGVorbis(); +}; + + +class AudioStreamOGGVorbis : public AudioStream { + + OBJ_TYPE(AudioStreamOGGVorbis,AudioStream); + + String file; +public: + + Ref<AudioStreamPlayback> instance_playback() { + Ref<AudioStreamPlaybackOGGVorbis> pb = memnew( AudioStreamPlaybackOGGVorbis ); + pb->set_file(file); + return pb; + } + + void set_file(const String& p_file) { file=p_file; } - AudioStreamOGGVorbis(); - ~AudioStreamOGGVorbis(); }; class ResourceFormatLoaderAudioStreamOGGVorbis : public ResourceFormatLoader { |