[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog backend/sound_handler_sdl.cpp b...
From: |
Tomas Groth |
Subject: |
[Gnash-commit] gnash ChangeLog backend/sound_handler_sdl.cpp b... |
Date: |
Fri, 17 Nov 2006 14:52:19 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Tomas Groth <tgc> 06/11/17 14:52:19
Modified files:
. : ChangeLog
backend : sound_handler_sdl.cpp sound_handler_sdl.h
Log message:
Re-structured the code a bit to make pointer handling safer, and
changed from structs to classes. General cleanups... Added doxygen comments.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.1651&r2=1.1652
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/sound_handler_sdl.cpp?cvsroot=gnash&r1=1.36&r2=1.37
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/sound_handler_sdl.h?cvsroot=gnash&r1=1.11&r2=1.12
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.1651
retrieving revision 1.1652
diff -u -b -r1.1651 -r1.1652
--- ChangeLog 17 Nov 2006 13:49:45 -0000 1.1651
+++ ChangeLog 17 Nov 2006 14:52:19 -0000 1.1652
@@ -1,3 +1,9 @@
+2006-11-17 Tomas Groth Christensen <address@hidden>
+
+ * backend/sound_handler_sdl.{h,cpp}: Re-structured the code a bit
+ to make pointer handling safer, and changed from structs to
+ classes. General cleanups... Added doxygen comments.
+
2006-11-17 Sandro Santilli <address@hidden>
* server/swf/tag_loaders.cpp (import_loader): don't allow
Index: backend/sound_handler_sdl.cpp
===================================================================
RCS file: /sources/gnash/gnash/backend/sound_handler_sdl.cpp,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -b -r1.36 -r1.37
--- backend/sound_handler_sdl.cpp 14 Nov 2006 21:11:45 -0000 1.36
+++ backend/sound_handler_sdl.cpp 17 Nov 2006 14:52:19 -0000 1.37
@@ -198,10 +198,10 @@
m_sound_data[handle_id]->data_size += adjusted_size;
for(uint32_t i=0; i <
m_sound_data[handle_id]->m_active_sounds.size(); i++) {
- m_sound_data[handle_id]->m_active_sounds[i]->data =
m_sound_data[handle_id]->data;
+
m_sound_data[handle_id]->m_active_sounds[i]->set_data(m_sound_data[handle_id]->data);
m_sound_data[handle_id]->m_active_sounds[i]->data_size
= m_sound_data[handle_id]->data_size;
m_sound_data[handle_id]->m_active_sounds[i]->position =
m_sound_data[handle_id]->data_size;
- m_sound_data[handle_id]->m_active_sounds[i]->raw_data =
m_sound_data[handle_id]->data;
+
m_sound_data[handle_id]->m_active_sounds[i]->set_raw_data(m_sound_data[handle_id]->data);
}
} else if (m_sound_data[handle_id]->format == FORMAT_MP3) {
@@ -217,7 +217,7 @@
// If playback has already started, we also update the active
sounds
for(uint32_t i=0; i <
m_sound_data[handle_id]->m_active_sounds.size(); i++) {
- m_sound_data[handle_id]->m_active_sounds[i]->data =
m_sound_data[handle_id]->data;
+
m_sound_data[handle_id]->m_active_sounds[i]->set_data(m_sound_data[handle_id]->data);
m_sound_data[handle_id]->m_active_sounds[i]->data_size
= m_sound_data[handle_id]->data_size;
}
@@ -257,7 +257,7 @@
// Copy data-info to the active_sound
sound->data_size = m_sound_data[sound_handle]->data_size;
- sound->data = m_sound_data[sound_handle]->data;
+ sound->set_data(m_sound_data[sound_handle]->data);
// Set the given options of the sound
if (start_position < 0) sound->position = 0;
@@ -300,13 +300,13 @@
mad_synth_init(&sound->synth);
#endif
- sound->raw_data = 0;
+ sound->set_raw_data(NULL);
sound->raw_position = 0;
sound->raw_data_size = 0;
} else {
sound->raw_data_size = m_sound_data[sound_handle]->data_size;
- sound->raw_data = m_sound_data[sound_handle]->data;
+ sound->set_raw_data(m_sound_data[sound_handle]->data);
sound->raw_position = 0;
sound->position = m_sound_data[sound_handle]->data_size;
@@ -356,7 +356,7 @@
mad_frame_finish(&m_sound_data[sound_handle]->m_active_sounds[i]->frame);
mad_stream_finish(&m_sound_data[sound_handle]->m_active_sounds[i]->stream);
#endif
- delete[]
m_sound_data[sound_handle]->m_active_sounds[i]->raw_data;
+
m_sound_data[sound_handle]->m_active_sounds[i]->delete_raw_data();
m_sound_data[sound_handle]->m_active_sounds.erase(m_sound_data[sound_handle]->m_active_sounds.begin()
+ i);
soundsPlaying--;
@@ -407,7 +407,7 @@
mad_frame_finish(&m_sound_data[j]->m_active_sounds[i]->frame);
mad_stream_finish(&m_sound_data[j]->m_active_sounds[i]->stream);
#endif
- delete[]
m_sound_data[j]->m_active_sounds[i]->raw_data;
+
m_sound_data[j]->m_active_sounds[i]->delete_raw_data();
m_sound_data[j]->m_active_sounds.erase(m_sound_data[j]->m_active_sounds.begin()
+ i);
soundsPlaying--;
@@ -614,6 +614,30 @@
return new SDL_sound_handler;
}
+
+// Pointer handling and checking functions
+uint8_t* active_sound::get_raw_data_ptr(unsigned long int pos) {
+ assert(raw_data_size > pos);
+ return raw_data + pos;
+}
+
+uint8_t* active_sound::get_data_ptr(unsigned long int pos) {
+ assert(data_size > pos);
+ return data + pos;
+}
+
+void active_sound::set_raw_data(uint8_t* iraw_data) {
+ raw_data = iraw_data;
+}
+
+void active_sound::set_data(uint8_t* idata) {
+ data = idata;
+}
+
+void active_sound::delete_raw_data() {
+ delete [] raw_data;
+}
+
// AS-volume adjustment
void adjust_volume(int16_t* data, int size, int volume)
{
@@ -657,8 +681,8 @@
} else {
startpos = sound->raw_position;
}
- assert(sound->raw_data_size > startpos);
- int16_t* data = (int16_t*) (sound->raw_data + startpos);
+
+ int16_t* data = (int16_t*) (sound->get_raw_data_ptr(startpos));
for (unsigned int i=0; i < length/2; i+=2) {
float left =
(float)(*sound->envelopes)[sound->current_env].m_level0 / 32768.0;
@@ -681,13 +705,32 @@
}
-/// The callback function which refills the buffer with data
-/// We run through all of the sounds, and mix all of the active sounds
-/// into the stream given by the callback.
-/// If sound is compresssed (mp3) a mp3-frame is decoded into a buffer,
-/// and resampled if needed. When the buffer has been sampled, another
-/// frame is decoded until all frames has been decoded.
-/// If a sound is looping it will be decoded from the beginning again.
+// Prepare for mixing/adding (volume adjustments) and mix/add.
+static void
+do_mixing(Uint8* stream, active_sound* sound, Uint8* data, unsigned int
mix_length, unsigned int volume) {
+ // If the volume needs adjustments we call a function to do that
+ if (volume != 100) {
+ adjust_volume((int16_t*)(data), mix_length, volume);
+ } else if (sound->envelopes != NULL) {
+ use_envelopes(sound, mix_length);
+ }
+
+ // Mix the raw data
+ SDL_MixAudio((Uint8*)(stream),(const Uint8*) (data), mix_length,
SDL_MIX_MAXVOLUME);
+
+ // Update sound info
+ sound->raw_position += mix_length;
+ sound->samples_played += mix_length;
+}
+
+
+// The callback function which refills the buffer with data
+// We run through all of the sounds, and mix all of the active sounds
+// into the stream given by the callback.
+// If sound is compresssed (mp3) a mp3-frame is decoded into a buffer,
+// and resampled if needed. When the buffer has been sampled, another
+// frame is decoded until all frames has been decoded.
+// If a sound is looping it will be decoded from the beginning again.
static void
sdl_audio_callback (void *udata, Uint8 *stream, int buffer_length_in)
@@ -717,7 +760,6 @@
Uint8* buffer = stream;
memset(buffer, 0, buffer_length);
-
// call NetStream audio callbacks
if (handler->m_aux_streamer.size() > 0)
{
@@ -745,7 +787,7 @@
active_sound* sound =
handler->m_sound_data[i]->m_active_sounds[j];
// When the current sound dont have enough decoded data
to fill the buffer,
- // we first mix what is alreadt decoded, then decode
some more data, and
+ // we first mix what is already decoded, then decode
some more data, and
// mix some more until the buffer is full. If a sound
loops the magic
// happens here ;)
if (sound->raw_data_size - sound->raw_position <
buffer_length
@@ -754,26 +796,12 @@
// First we mix what is decoded
unsigned int index = 0;
if (sound->raw_data_size - sound->raw_position
> 0) {
- // If the volume needs adjustments we
call a function to do that
- if (handler->m_sound_data[i]->volume !=
100) {
-
adjust_volume((int16_t*)(sound->raw_data + sound->raw_position),
- sound->raw_data_size -
sound->raw_position,
-
handler->m_sound_data[i]->volume);
- } else if (sound->envelopes != NULL) {
- assert(sound->raw_data_size >
sound->raw_position);
- use_envelopes(sound,
sound->raw_data_size - sound->raw_position);
- }
+ index = sound->raw_data_size -
sound->raw_position;
- // Test if we will get problems...
Should not happen...
- assert(sound->raw_data_size >
sound->raw_position);
+ do_mixing(stream, sound,
sound->get_raw_data_ptr(sound->raw_position),
+ index,
handler->m_sound_data[i]->volume);
- SDL_MixAudio(stream, (const
Uint8*)(sound->raw_data + sound->raw_position),
- sound->raw_data_size -
sound->raw_position,
- SDL_MIX_MAXVOLUME);
- index = sound->raw_data_size -
sound->raw_position;
}
- sound->raw_position += index;
- sound->samples_played += index;
// Then we decode some data
int outsize = 0;
@@ -791,7 +819,7 @@
}
// Test if we will get problems...
Should not happen...
- assert(sound->data_size >=
sound->position);
+ assert(sound->data_size >
sound->position);
// temp raw buffer
Uint8* tmp_raw_buffer;
@@ -808,7 +836,7 @@
int framesize;
bytes_decoded =
av_parser_parse(sound->parser, sound->cc, &frame, &framesize,
-
(uint8_t *)(sound->data + sound->position), sound->data_size - sound->position,
+
(uint8_t *)(sound->get_data_ptr(sound->position)), sound->data_size -
sound->position,
0 ,0);
//pts, dts
int tmp = 0;
@@ -828,7 +856,7 @@
#elif defined(USE_MAD)
// Setup the mad decoder
- mad_stream_buffer(&sound->stream,
sound->data+sound->position, sound->data_size-sound->position);
+ mad_stream_buffer(&sound->stream,
sound->get_data_ptr(sound->position), sound->data_size-sound->position);
int ret;
const unsigned char* old_next_frame =
sound->stream.next_frame;
@@ -897,9 +925,9 @@
}
#endif
-
// If we need to convert samplerate...
if (outsize > 0 &&
handler->m_sound_data[i]->sample_rate != handler->audioSpec.freq) {
+
int16_t* adjusted_data = 0;
int adjusted_size = 0;
int sample_count = outsize /
((handler->m_sound_data[i]->stereo == true) ? 4 : 2);
@@ -910,6 +938,7 @@
// Hopefully this wont happen
if (!adjusted_data) {
+
gnash::log_warning("Error in sound sample convertion");
continue;
}
@@ -923,79 +952,51 @@
}
Uint8* tmp_buf = new Uint8[decoded_size
+ tmp_raw_buffer_size];
- memcpy(tmp_buf, sound->raw_data,
decoded_size);
+ sound->raw_data_size = 1;
+ memcpy(tmp_buf,
sound->get_raw_data_ptr(0), decoded_size);
memcpy(tmp_buf, tmp_raw_buffer,
tmp_raw_buffer_size);
decoded_size += tmp_raw_buffer_size;
- delete[] sound->raw_data;
- sound->raw_data = tmp_buf;
+ sound->delete_raw_data();
+ sound->set_raw_data(tmp_buf);
delete[] tmp_raw_buffer;
+ // no more to decode from this sound,
so we break the loop
+ if (sound->data_size <= sound->position
&& sound->loop_count == 0) {
+ break;
+ }
+
} // end of "decode min. bufferlength data"
while loop
sound->raw_data_size = decoded_size;
sound->raw_position = 0;
- // Test if we will get problems... Should not
happen...
- assert(buffer_length - index <
sound->raw_data_size);
-
- // If the volume needs adjustments we call a
function to do that
- if (handler->m_sound_data[i]->volume != 100) {
-
adjust_volume((int16_t*)(sound->raw_data + sound->raw_position),
- sound->raw_data_size -
sound->raw_position,
-
handler->m_sound_data[i]->volume);
- } else if (sound->envelopes != NULL) {
- assert(buffer_length >= index);
- use_envelopes(sound, buffer_length -
index);
+ // Determine how much should be mixed
+ unsigned int mix_length = 0;
+ if (decoded_size >= buffer_length - index) {
+ mix_length = buffer_length - index;
+ } else {
+ mix_length = decoded_size;
}
- // Then we mix the newly decoded data
- SDL_MixAudio((Uint8*)(stream+index),(const
Uint8*) sound->raw_data,
- buffer_length - index,
- SDL_MIX_MAXVOLUME);
-
- sound->raw_position = buffer_length - index;
- sound->samples_played += buffer_length - index;
+ do_mixing(stream+index, sound,
sound->get_raw_data_ptr(0), mix_length, handler->m_sound_data[i]->volume);
// When the current sound has enough decoded data to
fill
// the buffer, we do just that.
} else if (sound->raw_data_size - sound->raw_position >
buffer_length ) {
- // If the volume needs adjustments we call a
function to do that
- if (handler->m_sound_data[i]->volume != 100) {
-
adjust_volume((int16_t*)(sound->raw_data + sound->raw_position),
- sound->raw_data_size -
sound->raw_position,
-
handler->m_sound_data[i]->volume);
- } else if (sound->envelopes != NULL) {
- use_envelopes(sound, buffer_length);
- }
-
- // Mix the raw data
- SDL_MixAudio((Uint8*)(stream),(const Uint8*)
(sound->raw_data + sound->raw_position),
- buffer_length,
- SDL_MIX_MAXVOLUME);
-
- sound->raw_position += buffer_length;
- sound->samples_played += buffer_length;
+ do_mixing(stream, sound,
sound->get_raw_data_ptr(sound->raw_position),
+ buffer_length,
handler->m_sound_data[i]->volume);
// When the current sound doesn't have anymore data to
decode,
// and doesn't loop (anymore), but still got unplayed
data,
// we put the last data on the stream
} else if (sound->raw_data_size - sound->raw_position
<= buffer_length && sound->raw_data_size > sound->raw_position+1) {
- // If the volume needs adjustments we call a
function to do that
- if (handler->m_sound_data[i]->volume != 100) {
-
adjust_volume((int16_t*)(sound->raw_data + sound->raw_position),
- sound->raw_data_size -
sound->raw_position,
-
handler->m_sound_data[i]->volume);
- } else if (sound->envelopes != NULL) {
- use_envelopes(sound,
sound->raw_data_size - sound->raw_position);
- }
- // Mix the remaining data
- SDL_MixAudio((Uint8*)(stream),(const Uint8*)
(sound->raw_data + sound->raw_position),
- sound->raw_data_size -
sound->raw_position,
- SDL_MIX_MAXVOLUME);
+ do_mixing(stream, sound,
sound->get_raw_data_ptr(sound->raw_position),
+ sound->raw_data_size -
sound->raw_position, handler->m_sound_data[i]->volume);
+
sound->raw_position = sound->raw_data_size;
}
@@ -1009,7 +1010,7 @@
mad_frame_finish(&sound->frame);
mad_stream_finish(&sound->stream);
#endif
- delete[] sound->raw_data;
+ sound->delete_raw_data();
handler->m_sound_data[i]->m_active_sounds.erase(handler->m_sound_data[i]->m_active_sounds.begin()
+ j);
handler->soundsPlaying--;
Index: backend/sound_handler_sdl.h
===================================================================
RCS file: /sources/gnash/gnash/backend/sound_handler_sdl.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- backend/sound_handler_sdl.h 2 Nov 2006 07:31:34 -0000 1.11
+++ backend/sound_handler_sdl.h 17 Nov 2006 14:52:19 -0000 1.12
@@ -30,155 +30,182 @@
#include <SDL_audio.h>
#include <pthread.h>
-// Used to hold the info about active sounds
-typedef struct
+/// Used to hold the info about active sounds
+class active_sound
{
+public:
#ifdef USE_FFMPEG
- // ffmpeg stuff
+ /// ffmpeg stuff
AVCodec *codec;
AVCodecContext *cc;
AVCodecParserContext* parser;
#elif defined(USE_MAD)
- // mad stuff
+ /// mad stuff
mad_stream stream;
mad_frame frame;
mad_synth synth;
#endif
- // data size
+ /// The size of the undecoded data
unsigned long data_size;
- // position in the stream
+ /// Current decoding position in the stream
unsigned long position;
- // The compressed data
- uint8_t* data;
-
- // data size
+ /// Size of the decoded data
unsigned long raw_data_size;
- // position in the raw stream
+ /// Current playing position in the decoded stream
unsigned long raw_position;
- // The decompressed data
- uint8_t* raw_data;
-
- /// Numbers of loops: -1 means loop forever, 0 means play once
+ /// Numbers of loops: -1 means loop forever, 0 means play once.
+ /// For every loop completed, it is decremented.
long loop_count;
- // Offset, only used with mp3 streams
+ /// Offset to make playback start in-sync, only used with mp3 streams.
unsigned int offset;
- // Envelopes
+ /// Sound envelopes for the current sound, which determine the volume
level
+ /// from a given position. Only used with sound events.
std::vector<gnash::sound_handler::sound_envelope>* envelopes;
- // Current envelope
+ /// Index of current envelope.
uint32_t current_env;
- // Number if samples played
+ /// Number of samples played so far.
unsigned long samples_played;
-} active_sound;
+ /// Returns the data pointer in the undecoded datastream
+ /// for the given position. Boundaries are checked.
+ uint8_t* get_data_ptr(unsigned long int pos);
+ /// Returns the data pointer in the decoded datastream
+ /// for the given position. Boundaries are checked.
+ uint8_t* get_raw_data_ptr(unsigned long int pos);
-// Used to hold the sounddata when doing on-demand-decoding
-typedef struct
+ /// Set the undecoded data pointer
+ void set_data(uint8_t*);
+
+ /// Set the decoded data pointer
+ void set_raw_data(uint8_t*);
+
+ /// Deletes the decoded data
+ void delete_raw_data();
+
+private:
+ /// The undecoded data
+ uint8_t* data;
+
+ /// The decoded data
+ uint8_t* raw_data;
+
+};
+
+
+/// Used to hold the sounddata when doing on-demand-decoding
+class sound_data
{
- // The (un)compressed data
+public:
+ /// The undecoded data
uint8_t* data;
- // data format
+ /// Format of the sound (MP3, raw, etc).
int format;
- // data size
+ /// The size of the undecoded data
long data_size;
- // stereo or not
+ /// Stereo or not
bool stereo;
- // number of samples
+ /// Number of samples
int sample_count;
- // sample rate
+ /// Sample rate
int sample_rate;
- // Volume for AS-sounds, range: 0-100
- // It's the SWF range that is represented here
+ /// Volume for AS-sounds, range: 0-100.
+ /// It's the SWF range that is represented here.
int volume;
- // active sounds being playes
+ /// Vector containing the active instances of this sounds being played
std::vector<active_sound*> m_active_sounds;
-} sound_data;
+};
// Use SDL and ffmpeg/mad/nothing to handle sounds.
-struct SDL_sound_handler : public gnash::sound_handler
+class SDL_sound_handler : public gnash::sound_handler
{
- // NetStream audio callbacks
+public:
+ /// NetStream audio callbacks
gnash::hash< void* /* owner */, aux_streamer_ptr /* callback */>
m_aux_streamer; //vv
- // Sound data.
+ /// Vector containing all sounds.
std::vector<sound_data*> m_sound_data;
- // Is sound device opened?
+ /// Is sound device opened?
bool soundOpened;
- // SDL_audio specs
+ /// The SDL_audio specs
SDL_AudioSpec audioSpec;
- // Keeps track of numbers of playing sounds
+ /// Keeps track of numbers of playing sounds
int soundsPlaying;
- // Is the audio muted?
+ /// Is the audio muted?
bool muted;
- // mutex for making sure threads doesn't mess things up
+ /// Mutex for making sure threads doesn't mess things up
pthread_mutex_t mutex;
SDL_sound_handler();
virtual ~SDL_sound_handler();
- // Called to create a sample.
+ /// Called to create a sound.
virtual int create_sound(void* data, int data_bytes,
int sample_count, format_type format,
int sample_rate, bool stereo);
- // this gets called when a stream gets more data
+ /// this gets called when a stream gets more data
virtual long fill_stream_data(void* data, int data_bytes,
int sample_count, int handle_id);
- // Play the index'd sample.
+ /// Play the index'd sample.
virtual void play_sound(int sound_handle, int loop_count, int offset,
long start_position,
std::vector<sound_envelope>* envelopes);
+ /// Stop the index'd sample.
virtual void stop_sound(int sound_handle);
- // this gets called when it's done with a sample.
+ /// This gets called when it's done with a sample.
virtual void delete_sound(int sound_handle);
- // this will stop all sounds playing.
+ /// This will stop all sounds playing.
virtual void stop_all_sounds();
- // returns the sound volume level as an integer from 0 to 100.
+ /// Returns the sound volume level as an integer from 0 to 100.
AS-script only.
virtual int get_volume(int sound_handle);
+ /// Sets the sound volume level as an integer from 0 to 100. AS-script
only.
virtual void set_volume(int sound_handle, int volume);
+ /// Gnash uses this to get info about a sound. Used when a stream needs
more data.
virtual void get_info(int sound_handle, int* format, bool* stereo);
- // gnash calls this to mute audio
+ /// Gnash calls this to mute audio.
virtual void mute();
- // gnash calls this to unmute audio
+ /// Gnash calls this to unmute audio.
virtual void unmute();
+ /// Gnash calls this to get the mute state.
virtual bool is_muted();
virtual void attach_aux_streamer(aux_streamer_ptr ptr, void* owner);
//vv
virtual void detach_aux_streamer(void* owner); //vv
- // Converts input data to the SDL output format.
+ /// Converts input data to the SDL output format.
virtual void convert_raw_data(int16_t** adjusted_data,
int* adjusted_size, void* data, int sample_count,
int sample_size, int sample_rate, bool stereo);
//vv