[Flac-dev] getting framesize in client

Miroslav Lichvar lichvarm at phoenix.inf.upol.cz
Sat Nov 9 15:55:02 PST 2002


On Sat, Nov 09, 2002 at 06:02:33PM +0100, Miroslav Lichvar wrote:
> On Fri, Nov 08, 2002 at 07:12:35PM -0800, Josh Coalson wrote:
> > Yeah, it's useful, so now there is a
> > FLAC__seekable_stream_decoder_get_decode_position() and
> > FLAC__file_decoder_get_decode_position().  I haven't documented
> > them yet but you can see an example in
> > src/metaflac/operations_shorthand_seektable.c where I use it
> > during seektable creation.
> 
> Ok, here is patch for "current bitrate" displaying in xmms plugin and

It doesn't display correctly near end of files, here is better one.
I'm sorry.

-- 
Miroslav Lichvar
-------------- next part --------------
--- src/plugin_xmms/plugin.c.orig	2002-11-07 18:40:44.000000000 +0100
+++ src/plugin_xmms/plugin.c	2002-11-10 00:40:20.000000000 +0100
@@ -58,6 +58,7 @@
 	unsigned channels;
 	unsigned sample_rate;
 	unsigned length_in_msec;
+	gchar *title;
 	AFormat sample_format;
 	int seek_to_in_sec;
 	FLAC__bool has_replaygain;
@@ -114,6 +115,10 @@
 #define SAMPLES_PER_WRITE 512
 static FLAC__int32 reservoir_[FLAC__MAX_BLOCK_SIZE * 2/*for overflow*/ * FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS];
 static FLAC__byte sample_buffer_[SAMPLES_PER_WRITE * FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS * (24/8)]; /* (24/8) for max bytes per sample */
+#define BITRATE_HIST_SEGMENT_MSEC 500
+/* 500ms * 50 = 25s should be enough */
+#define BITRATE_HIST_SIZE 50
+static unsigned bitrate_history[BITRATE_HIST_SIZE];
 static unsigned wide_samples_in_reservoir_ = 0;
 static FLAC__FileDecoder *decoder_ = 0;
 static file_info_struct file_info_;
@@ -188,7 +193,6 @@
 void FLAC_XMMS__play_file(char *filename)
 {
 	FILE *f;
-	gchar *ret;
 
 	wide_samples_in_reservoir_ = 0;
 	audio_error_ = false;
@@ -219,10 +223,8 @@
 		return;
 	}
 
-	ret = flac_format_song_title(filename);
-	flac_ip.set_info(ret, file_info_.length_in_msec, file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample, file_info_.sample_rate, file_info_.channels);
-
-	g_free(ret);
+	file_info_.title = flac_format_song_title(filename);
+	flac_ip.set_info(file_info_.title, file_info_.length_in_msec, file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample, file_info_.sample_rate, file_info_.channels);
 
 	file_info_.seek_to_in_sec = -1;
 	file_info_.play_thread_open = true;
@@ -304,6 +306,9 @@
 
 void *play_loop_(void *arg)
 {
+	unsigned written_time_last = 0, bh_index_last_w = 0, bh_index_last_o = BITRATE_HIST_SIZE;
+	FLAC__uint64 decode_position_last = 0;
+
 	(void)arg;
 
 	while(file_info_.is_playing) {
@@ -326,7 +331,8 @@
 				const unsigned n = min(wide_samples_in_reservoir_, SAMPLES_PER_WRITE);
 				const unsigned delta = n * channels;
 				int bytes;
-				unsigned i;
+				unsigned i, written_time, bh_index_w;
+				FLAC__uint64 decode_position;
 
 				if(flac_cfg.output.replaygain.enable && file_info_.has_replaygain) {
 					bytes = (int)FLAC__plugin_common__apply_gain(
@@ -365,6 +371,20 @@
 					xmms_usleep(10000);
 				if(file_info_.is_playing && file_info_.seek_to_in_sec == -1)
 					flac_ip.output->write_audio(sample_buffer_, bytes);
+
+				/* compute current bitrate */
+				
+				written_time = flac_ip.output->written_time();
+				bh_index_w = written_time / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE ;
+				if(bh_index_w != bh_index_last_w && wide_samples_in_reservoir_ < SAMPLES_PER_WRITE) {
+					bh_index_last_w = bh_index_w;
+					if(!FLAC__file_decoder_get_decode_position(decoder_, &decode_position))
+						decode_position = 0;
+
+					bitrate_history[(bh_index_w + BITRATE_HIST_SIZE - 1) % BITRATE_HIST_SIZE] = decode_position > decode_position_last && written_time > written_time_last ? 8000 * (decode_position - decode_position_last) / (written_time - written_time_last) : file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample;
+					decode_position_last = decode_position;
+					written_time_last = written_time;
+				}
 			}
 			else {
 				file_info_.eof = true;
@@ -378,11 +398,20 @@
 			unsigned target_sample = (unsigned)(distance * (double)file_info_.total_samples);
 			if(FLAC__file_decoder_seek_absolute(decoder_, (FLAC__uint64)target_sample)) {
 				flac_ip.output->flush(file_info_.seek_to_in_sec * 1000);
+				bh_index_last_w = bh_index_last_o = file_info_.seek_to_in_sec * 1000 / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
 				file_info_.seek_to_in_sec = -1;
 				file_info_.eof = false;
 				wide_samples_in_reservoir_ = 0;
 			}
 		}
+		else {
+			/* display the right bitrate from history */
+			unsigned bh_index_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
+			if(bh_index_o != bh_index_last_o && bh_index_last_w != bh_index_o) {
+				bh_index_last_o = bh_index_o;
+				flac_ip.set_info(file_info_.title, file_info_.length_in_msec, bitrate_history[bh_index_o], file_info_.sample_rate, file_info_.channels);
+			}
+		}
 	}
 
 	safe_decoder_finish_(decoder_);
@@ -390,6 +419,8 @@
 	/* are these two calls necessary? */
 	flac_ip.output->buffer_free();
 	flac_ip.output->buffer_free();
+	
+	g_free(file_info_.title);
 
 	pthread_exit(NULL);
 	return 0; /* to silence the compiler warning about not returning a value */


More information about the Flac-dev mailing list