[Scummvm-cvs-logs] SF.net SVN: scummvm:[39009] scummvm/trunk/engines/sci/sfx

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Sun Mar 1 07:02:43 CET 2009


Revision: 39009
          http://scummvm.svn.sourceforge.net/scummvm/?rev=39009&view=rev
Author:   fingolfin
Date:     2009-03-01 06:02:42 +0000 (Sun, 01 Mar 2009)

Log Message:
-----------
SCI: Removed unused pause/resume methods from the mixer, and rewrote the feeds handling to use Common::List

Modified Paths:
--------------
    scummvm/trunk/engines/sci/sfx/mixer.cpp
    scummvm/trunk/engines/sci/sfx/mixer.h

Modified: scummvm/trunk/engines/sci/sfx/mixer.cpp
===================================================================
--- scummvm/trunk/engines/sci/sfx/mixer.cpp	2009-03-01 06:02:34 UTC (rev 39008)
+++ scummvm/trunk/engines/sci/sfx/mixer.cpp	2009-03-01 06:02:42 UTC (rev 39009)
@@ -23,6 +23,7 @@
  *
  */
 
+#include "common/list.h"
 #include "common/mutex.h"
 #include "common/system.h"
 
@@ -73,7 +74,7 @@
 	int left, right;
 };
 
-struct sfx_pcm_feed_state_t {
+struct PCMFeedState {
 	sfx_pcm_feed_t *feed;
 
 	/* The following fields are for use by the mixer only and must not be
@@ -85,8 +86,11 @@
 	int frame_bufstart; /* Left-over frames at the beginning of the buffer */
 	int mode; /* Whether the feed is alive or pending destruction */
 
-	int pending_review; /* Timestamp needs to be checked for this stream */
+	bool pending_review; /* Timestamp needs to be checked for this stream */
 	twochannel_data ch_old, ch_new; /* Intermediate results of output computation */
+
+	PCMFeedState(sfx_pcm_feed_t *f);
+	~PCMFeedState();
 };
 
 struct mixer_private {
@@ -106,17 +110,12 @@
 	int max_delta; /* maximum observed time delta (using 'frames' as a metric unit) */
 	int delta_observations; /* Number of times we played; confidence measure for max_delta */
 
-	/* Pause data */
-	int paused;
-
 	sfx_pcm_config_t conf;
 	int _framesize;
 	Audio::AppendableAudioStream *_audioStream;
 	Audio::SoundHandle _soundHandle;
 
-	int feeds_nr;
-	int feeds_allocd;
-	sfx_pcm_feed_state_t *feeds;
+	Common::List<PCMFeedState> _feeds;
 };
 
 #define P ((struct mixer_private *)(self->private_bits))
@@ -132,17 +131,12 @@
 	P->compbuf_l = (int32*)sci_malloc(sizeof(int32) * BUF_SIZE);
 	P->compbuf_r = (int32*)sci_malloc(sizeof(int32) * BUF_SIZE);
 	P->played_this_second = 0;
-	P->paused = 0;
 	
 	P->conf.rate = g_system->getMixer()->getOutputRate();
 	P->conf.stereo = SFX_PCM_STEREO_LR;
 	P->conf.format = SFX_PCM_FORMAT_S16_NATIVE;
 	P->_framesize = SFX_PCM_FRAME_SIZE(P->conf);
 
-	P->feeds_nr = 0;
-	P->feeds_allocd = 0;
-	P->feeds = 0;
-	
 	int flags = Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_STEREO;
 #ifdef SCUMM_LITTLE_ENDIAN
 	flags |= Audio::Mixer::FLAG_LITTLE_ENDIAN;
@@ -180,22 +174,30 @@
 	return rv;
 }
 
+PCMFeedState::PCMFeedState(sfx_pcm_feed_t *f) : feed(f) {
+	buf = 0;
+	buf_size = 0;
+	spd = scount = urat(0, 1);
+	frame_bufstart = 0;
+	mode = SFX_PCM_FEED_MODE_ALIVE;
+	frame_bufstart = 0;
+
+	/* If the feed can't provide us with timestamps, we don't need to wait for it to do so */
+	pending_review = (feed->get_timestamp) ? true : false;
+
+	memset(&ch_old, 0, sizeof(twochannel_data));
+	memset(&ch_new, 0, sizeof(twochannel_data));
+}
+
+PCMFeedState::~PCMFeedState() {
+	feed->destroy(feed);
+	free(buf);
+}
+
 static void mix_subscribe(sfx_pcm_mixer_t *self, sfx_pcm_feed_t *feed) {
-	sfx_pcm_feed_state_t *fs;
 	ACQUIRE_LOCK();
-	if (!P->feeds) {
-		P->feeds_allocd = 2;
-		P->feeds = (sfx_pcm_feed_state_t*)sci_malloc(sizeof(sfx_pcm_feed_state_t)
-		              * P->feeds_allocd);
-	} else if (P->feeds_allocd == P->feeds_nr) {
-		P->feeds_allocd += 2;
-		P->feeds = (sfx_pcm_feed_state_t*)sci_realloc(P->feeds,
-		              sizeof(sfx_pcm_feed_state_t)
-		              * P->feeds_allocd);
-	}
 
-	fs = P->feeds + P->feeds_nr++;
-	fs->feed = feed;
+	PCMFeedState fs(feed);
 
 	feed->frame_size = SFX_PCM_FRAME_SIZE(feed->conf);
 
@@ -205,7 +207,7 @@
 		/ P->conf.rate;
 	*/
 	/* For the sake of people without 64 bit CPUs: */
-	fs->buf_size = 2 + /* Additional safety */
+	fs.buf_size = 2 + /* Additional safety */
 	               (BUF_SIZE *
 	                (1 + (feed->conf.rate / P->conf.rate)));
 	fprintf(stderr, " ---> %d/%d/%d/%d = %d\n",
@@ -213,91 +215,30 @@
 	        feed->conf.rate,
 	        P->conf.rate,
 	        feed->frame_size,
-	        fs->buf_size);
+	        fs.buf_size);
 
-	fs->buf = (byte*)sci_malloc(fs->buf_size * feed->frame_size);
-	fprintf(stderr, " ---> --> %d for %p at %p\n", fs->buf_size * feed->frame_size, (void *)fs, (void *)fs->buf);
-	{
-		int i;
-		for (i = 0; i < fs->buf_size * feed->frame_size; i++)
-			fs->buf[i] = 0xa5;
-	}
-	fs->scount = urat(0, 1);
-	fs->spd = urat(feed->conf.rate, P->conf.rate);
-	fs->scount.den = fs->spd.den;
-	fs->ch_old.left = 0;
-	fs->ch_old.right = 0;
-	fs->ch_new.left = 0;
-	fs->ch_new.right = 0;
-	fs->mode = SFX_PCM_FEED_MODE_ALIVE;
+	fs.buf = (byte*)sci_malloc(fs.buf_size * feed->frame_size);
+	memset(fs.buf, 0xa5, fs.buf_size * feed->frame_size);
+	fs.scount = urat(0, 1);
+	fs.spd = urat(feed->conf.rate, P->conf.rate);
+	fs.scount.den = fs.spd.den;
 
-	/* If the feed can't provide us with timestamps, we don't need to wait for it to do so */
-	fs->pending_review = (feed->get_timestamp) ? 1 : 0;
-
-	fs->frame_bufstart = 0;
-
 #ifdef DEBUG
 	sciprintf("[soft-mixer] Subscribed %s-%x (%d Hz, %d/%x) at %d+%d/%d, buffer size %d\n",
 	          feed->debug_name, feed->debug_nr, feed->conf.rate, feed->conf.stereo, feed->conf.format,
 	          fs->spd.val, fs->spd.nom, fs->spd.den, fs->buf_size);
 #endif
-	RELEASE_LOCK();
-}
 
+	P->_feeds.push_back(fs);
 
-static void _mix_unsubscribe(sfx_pcm_mixer_t *self, sfx_pcm_feed_t *feed) {
-	int i;
-#ifdef DEBUG
-	sciprintf("[soft-mixer] Unsubscribing %s-%x\n", feed->debug_name, feed->debug_nr);
-#endif
-	for (i = 0; i < P->feeds_nr; i++) {
-		sfx_pcm_feed_state_t *fs = P->feeds + i;
-
-		if (fs->feed == feed) {
-			feed->destroy(feed);
-
-			if (fs->buf)
-				free(fs->buf);
-
-			P->feeds_nr--;
-
-			/* Copy topmost into deleted so that we don't have any holes */
-			if (i != P->feeds_nr)
-				P->feeds[i] = P->feeds[P->feeds_nr];
-
-			if (P->feeds_allocd > 8 && P->feeds_allocd > (P->feeds_nr << 1)) {
-				/* Limit memory waste */
-				P->feeds_allocd >>= 1;
-				P->feeds
-				= (sfx_pcm_feed_state_t*)sci_realloc(P->feeds,
-				                                     sizeof(sfx_pcm_feed_state_t)
-				                                     * P->feeds_allocd);
-			}
-
-			for (i = 0; i < P->feeds_nr; i++)
-				fprintf(stderr, "  Feed #%d: %s-%x\n",
-				        i, P->feeds[i].feed->debug_name,
-				        P->feeds[i].feed->debug_nr);
-
-			return;
-		}
-	}
-
-	fprintf(stderr, "[sfx-mixer] Assertion failed: Deleting invalid feed %p out of %d\n",
-	        (void *)feed, P->feeds_nr);
-
-	BREAKPOINT();
+	RELEASE_LOCK();
 }
 
+
 static void mix_exit(sfx_pcm_mixer_t *self) {
 	g_system->getMixer()->stopHandle(P->_soundHandle);
 	P->_audioStream = 0;
 
-	ACQUIRE_LOCK();
-	while (P->feeds_nr)
-		_mix_unsubscribe(self, P->feeds[0].feed);
-	RELEASE_LOCK();
-
 	free(P->outbuf);
 	free(P->writebuf);
 
@@ -527,11 +468,12 @@
 static volatile int xx_offset;
 static volatile int xx_size;
 
-static void mix_compute_input_linear(sfx_pcm_mixer_t *self, int add_result,
+static void mix_compute_input_linear(sfx_pcm_mixer_t *self,
+									 const Common::List<PCMFeedState>::iterator &fs,
 									 int len, sfx_timestamp_t *ts, sfx_timestamp_t base_ts) {
-/* if add_result is non-zero, P->outbuf should be added to rather than overwritten. */
 /* base_ts is the timestamp for the first frame */
-	sfx_pcm_feed_state_t *fs = P->feeds + add_result;
+/* if add_result is non-zero, P->outbuf should be added to rather than overwritten. */
+	const bool add_result = (P->_feeds.begin() != fs);
 	sfx_pcm_feed_t *f = fs->feed;
 	sfx_pcm_config_t conf = f->conf;
 	int use_16 = conf.format & SFX_PCM_FORMAT_16;
@@ -584,12 +526,8 @@
 			newmode = f->get_timestamp(f, ts);
 		ACQUIRE_LOCK();
 
-		fs = P->feeds + add_result;
-		/* Reset in case of status update */
-
 		switch (newmode) {
-
-		case PCM_FEED_TIMESTAMP: {
+		case PCM_FEED_TIMESTAMP:
 			/* Compute the number of frames the returned timestamp is in the future: */
 			delay_frames =
 			    sfx_timestamp_frame_diff(sfx_timestamp_renormalise(*ts, base_ts.frame_rate),
@@ -601,15 +539,12 @@
 			else
 				if (delay_frames > len)
 					delay_frames = len;
-			fs->pending_review = 0;
-		}
-		break;
+			fs->pending_review = false;
+			break;
 
 		case PCM_FEED_EMPTY:
 			fs->mode = SFX_PCM_FEED_MODE_DEAD;
-
-			/* ...fall through... */
-
+			// ...fall through...
 		case PCM_FEED_IDLE:
 			/* Clear audio buffer, if neccessary, and return */
 			if (!add_result) {
@@ -634,7 +569,6 @@
 		            - fs->frame_bufstart);
 
 	ACQUIRE_LOCK();
-	fs = P->feeds + add_result;
 
 	frames_read += fs->frame_bufstart;
 	frames_left = frames_read;
@@ -784,7 +718,7 @@
 
 	if (frames_read + delay_frames < frames_nr) {
 		if (f->get_timestamp) /* Can resume? */
-			fs->pending_review = 1;
+			fs->pending_review = true;
 		else
 			fs->mode = SFX_PCM_FEED_MODE_DEAD; /* Done. */
 	}
@@ -793,7 +727,6 @@
 static int mix_process_linear(sfx_pcm_mixer_t *self) {
 	ACQUIRE_LOCK();
 	{
-		int src_i; /* source feed index counter */
 		int frames_skip; /* Number of frames to discard, rather than to emit */
 		int buflen = mix_compute_buf_len(self, &frames_skip); /* Compute # of frames we must compute and write */
 		int fake_buflen;
@@ -832,10 +765,10 @@
 		}
 
 #if (DEBUG >= 1)
-		if (P->feeds_nr)
-			sciprintf("[soft-mixer] Mixing %d output frames on %d input feeds\n", buflen, P->feeds_nr);
+		if (P->_feeds.size())
+			sciprintf("[soft-mixer] Mixing %d output frames on %d input feeds\n", buflen, P->_feeds.size());
 #endif
-		if (P->feeds_nr && !P->paused) {
+		if (!P->_feeds.empty()) {
 			/* Below, we read out all feeds in case we have to skip frames first, then get the
 			** most current sound. 'fake_buflen' is either the actual buflen (for the last iteration)
 			** or a fraction of the buf length to discard.  */
@@ -852,8 +785,9 @@
 					frames_skip = -1; /* Mark us as being completely done */
 				}
 
-				for (src_i = 0; src_i < P->feeds_nr; src_i++) {
-					mix_compute_input_linear(self, src_i,
+				Common::List<PCMFeedState>::iterator iter = P->_feeds.begin();
+				for (iter = P->_feeds.begin(); iter != P->_feeds.end(); ++iter) {
+					mix_compute_input_linear(self, iter,
 					                         fake_buflen, &timestamp,
 					                         start_timestamp);
 
@@ -874,9 +808,13 @@
 					}
 				}
 				/* Destroy all feeds we finished */
-				for (src_i = 0; src_i < P->feeds_nr; src_i++)
-					if (P->feeds[src_i].mode == SFX_PCM_FEED_MODE_DEAD)
-						_mix_unsubscribe(self, P->feeds[src_i].feed);
+				iter = P->_feeds.begin();
+				while (iter != P->_feeds.end()) {
+					if (iter->mode == SFX_PCM_FEED_MODE_DEAD)
+						iter = P->_feeds.erase(iter);
+					else
+						++iter;
+				}
 			} while (frames_skip >= 0);
 
 		} else { /* Zero it out */
@@ -885,12 +823,12 @@
 		}
 
 #if (DEBUG >= 1)
-		if (P->feeds_nr)
+		if (P->_feeds.size())
 			sciprintf("[soft-mixer] Done mixing for this session, the result will be our next output buffer\n");
 #endif
 
 #if (DEBUG >= 3)
-		if (P->feeds_nr) {
+		if (P->_feeds.size()) {
 			int i;
 			sciprintf("[soft-mixer] Intermediate representation:\n");
 			for (i = 0; i < buflen; i++)
@@ -918,18 +856,6 @@
 	return SFX_OK;
 }
 
-static void mix_pause(sfx_pcm_mixer_t *self) {
-	ACQUIRE_LOCK();
-	P->paused = 1;
-	RELEASE_LOCK();
-}
-
-static void mix_resume(sfx_pcm_mixer_t *self) {
-	ACQUIRE_LOCK();
-	P->paused = 0;
-	RELEASE_LOCK();
-}
-
 sfx_pcm_mixer_t sfx_pcm_mixer_soft_linear = {
 	"soft-linear",
 	"0.1",
@@ -937,8 +863,6 @@
 	mix_init,
 	mix_exit,
 	mix_subscribe,
-	mix_pause,
-	mix_resume,
 	mix_process_linear,
 
 	NULL

Modified: scummvm/trunk/engines/sci/sfx/mixer.h
===================================================================
--- scummvm/trunk/engines/sci/sfx/mixer.h	2009-03-01 06:02:34 UTC (rev 39008)
+++ scummvm/trunk/engines/sci/sfx/mixer.h	2009-03-01 06:02:42 UTC (rev 39009)
@@ -56,14 +56,6 @@
 	**             (sfx_pcm_feed_t *) feed: The feed to subscribe to
 	*/
 
-	void (*pause)(sfx_pcm_mixer_t *self);
-	/* Pauses the processing of input and output
-	*/
-
-	void (*resume)(sfx_pcm_mixer_t *self);
-	/* Resumes the processing of input and output after a pause
-	*/
-
 	int (*process)(sfx_pcm_mixer_t *self);
 	/* Processes all feeds, mixes their results, and passes everything to the output device
 	** Returns  : (int) SFX_OK on success, SFX_ERROR otherwise (output device error or


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list