From 97413746173b4f872e8c72eba0e58d7092a93269 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Wed, 9 Sep 2015 18:50:52 -0300 Subject: Rewrite of the AudioStream API -Fixes long-standing issues regarding to playing a single stream multiple times simultanteously -Fixes wrong-looping, starting, caching, etc. Issues resulting from bad original design -Allows more interesting kinds of streams (stream graphs with streams inside streams!) in the future --- drivers/speex/audio_stream_speex.cpp | 174 ++++++++++++++++++----------------- drivers/speex/audio_stream_speex.h | 55 ++++++++--- 2 files changed, 128 insertions(+), 101 deletions(-) (limited to 'drivers/speex') 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;iget_len()); - int read = file->get_buffer(&data[0], data.size()); - memdelete(file); +void AudioStreamPlaybackSpeex::set_data(const Vector& 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 -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& 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 data; + String file; +public: + + Ref instance_playback() { + Ref 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); -- cgit v1.2.3 From 3514a87b371385cdc71a2ed36deb40cd0275fff5 Mon Sep 17 00:00:00 2001 From: reduz Date: Thu, 8 Oct 2015 14:50:18 -0300 Subject: fixed uninitialized memory issues in audio code --- drivers/speex/audio_stream_speex.cpp | 4 +++- drivers/speex/audio_stream_speex.h | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/speex') diff --git a/drivers/speex/audio_stream_speex.cpp b/drivers/speex/audio_stream_speex.cpp index 2440969345..1bb4952cc8 100644 --- a/drivers/speex/audio_stream_speex.cpp +++ b/drivers/speex/audio_stream_speex.cpp @@ -22,7 +22,7 @@ int AudioStreamPlaybackSpeex::mix(int16_t* p_buffer,int p_frames) { //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()) + if (!active || !playing || !data.size()) return 0; /* @@ -490,6 +490,8 @@ AudioStreamPlaybackSpeex::AudioStreamPlaybackSpeex() { stream_channels=1; stream_srate=1; stream_minbuff_size=1; + playing=false; + } diff --git a/drivers/speex/audio_stream_speex.h b/drivers/speex/audio_stream_speex.h index 570e846734..f0617b302f 100644 --- a/drivers/speex/audio_stream_speex.h +++ b/drivers/speex/audio_stream_speex.h @@ -29,7 +29,6 @@ class AudioStreamPlaybackSpeex : public AudioStreamPlayback { bool loops; int page_size; bool playing; - bool paused; bool packets_available; void unload(); -- cgit v1.2.3 From aad2bbdb6fb7c8217d7e75480b38e45f00cb3abd Mon Sep 17 00:00:00 2001 From: reduz Date: Thu, 8 Oct 2015 15:00:40 -0300 Subject: newline fixes --- drivers/speex/config.h | 104 +++++++++++++++++------------------ drivers/speex/lsp.h | 128 +++++++++++++++++++++---------------------- drivers/speex/speex_bind.cpp | 128 +++++++++++++++++++++---------------------- drivers/speex/speex_bind.h | 96 ++++++++++++++++---------------- 4 files changed, 228 insertions(+), 228 deletions(-) (limited to 'drivers/speex') diff --git a/drivers/speex/config.h b/drivers/speex/config.h index d31382702c..8c48e3b99d 100644 --- a/drivers/speex/config.h +++ b/drivers/speex/config.h @@ -1,52 +1,52 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef CONFIG_H -#define CONFIG_H - -/* An inline macro is required for use of the inline keyword as not all C compilers support */ -/* inline. It is officially C99 and C++ only */ - - -/* Use only fixed point arithmetic */ - -//#ifdef _MSC_VER -//#define inline _inline -//#endif - -#define FIXED_POINT 1 - -#ifdef _MSC_VER -#define inline __inline -#endif - -#endif /* ! CONFIG_H */ +/* + Copyright (C) 2003 Commonwealth Scientific and Industrial Research + Organisation (CSIRO) Australia + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of CSIRO Australia nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CONFIG_H +#define CONFIG_H + +/* An inline macro is required for use of the inline keyword as not all C compilers support */ +/* inline. It is officially C99 and C++ only */ + + +/* Use only fixed point arithmetic */ + +//#ifdef _MSC_VER +//#define inline _inline +//#endif + +#define FIXED_POINT 1 + +#ifdef _MSC_VER +#define inline __inline +#endif + +#endif /* ! CONFIG_H */ diff --git a/drivers/speex/lsp.h b/drivers/speex/lsp.h index 648652fb9e..b55bd42f2c 100644 --- a/drivers/speex/lsp.h +++ b/drivers/speex/lsp.h @@ -1,64 +1,64 @@ -/*---------------------------------------------------------------------------*\ -Original Copyright - FILE........: AK2LSPD.H - TYPE........: Turbo C header file - COMPANY.....: Voicetronix - AUTHOR......: James Whitehall - DATE CREATED: 21/11/95 - -Modified by Jean-Marc Valin - - This file contains functions for converting Linear Prediction - Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the - LSP coefficients are not in radians format but in the x domain of the - unit circle. - -\*---------------------------------------------------------------------------*/ -/** - @file lsp.h - @brief Line Spectral Pair (LSP) functions. -*/ -/* Speex License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __AK2LSPD__ -#define __AK2LSPD__ - -#include "arch.h" - -int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack); -void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack); - -/*Added by JMV*/ -void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin); - -void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes); - -#endif /* __AK2LSPD__ */ +/*---------------------------------------------------------------------------*\ +Original Copyright + FILE........: AK2LSPD.H + TYPE........: Turbo C header file + COMPANY.....: Voicetronix + AUTHOR......: James Whitehall + DATE CREATED: 21/11/95 + +Modified by Jean-Marc Valin + + This file contains functions for converting Linear Prediction + Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the + LSP coefficients are not in radians format but in the x domain of the + unit circle. + +\*---------------------------------------------------------------------------*/ +/** + @file lsp.h + @brief Line Spectral Pair (LSP) functions. +*/ +/* Speex License: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef __AK2LSPD__ +#define __AK2LSPD__ + +#include "arch.h" + +int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack); +void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack); + +/*Added by JMV*/ +void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin); + +void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes); + +#endif /* __AK2LSPD__ */ diff --git a/drivers/speex/speex_bind.cpp b/drivers/speex/speex_bind.cpp index 6e9eb638a2..d15bb3da8c 100644 --- a/drivers/speex/speex_bind.cpp +++ b/drivers/speex/speex_bind.cpp @@ -1,64 +1,64 @@ - -#include "memory.h" -#include "speex_bind.h" -#include -#ifdef __cplusplus -extern "C" { -#endif - -void *speex_alloc (int size) { - - uint8_t * mem = (uint8_t*)memalloc(size); - for(int i=0;i