commit f46f1fc9ae310294c48614390a2b59e7966e70e0
parent 9db2524bdf1e57b2bbac64c002064b86a66523cc
Author: Alexander Kojevnikov <alexander@kojevnikov.com>
Date: Thu, 20 May 2010 21:32:06 +1000
Show stream info in the window (issue 7)
Diffstat:
2 files changed, 86 insertions(+), 16 deletions(-)
diff --git a/src/spek-source.vala b/src/spek-source.vala
@@ -26,11 +26,18 @@ namespace Spek {
public int samples { get; construct; }
public int threshold { get; construct; }
// TODO: file a bug, cannot s/set/construct/
- public Callback callback {get; set; }
+ public DataCallback data_cb { get; set; }
+ public InfoCallback info_cb { get; set; }
+
public int64 duration { get; private set; default = 0; }
public int rate { get; private set; default = 0; }
+ public string audio_codec { get; private set; default = null; }
+ public uint bitrate { get; private set; default = 0; }
+ public int channels { get; private set; default = 0; }
+ public int depth { get; private set; default = 0; }
- public delegate void Callback (int sample, float[] values);
+ public delegate void DataCallback (int sample, float[] values);
+ public delegate void InfoCallback ();
private Pipeline pipeline = null;
private Element spectrum = null;
@@ -39,9 +46,12 @@ namespace Spek {
private float[] values;
private uint watch_id;
- public Source (string file_name, int bands, int samples, int threshold, Callback callback) {
+ public Source (
+ string file_name, int bands, int samples, int threshold,
+ DataCallback data_cb, InfoCallback info_cb) {
GLib.Object (file_name: file_name, bands: bands, samples: samples, threshold: threshold);
- this.callback = callback;
+ this.data_cb = data_cb;
+ this.info_cb = info_cb;
}
public void stop () {
@@ -84,10 +94,15 @@ namespace Spek {
var caps = pad.get_caps ();
for (int i = 0; i < caps.get_size (); i++) {
var structure = caps.get_structure (i);
- int rate;
- if (structure.get_int ("rate", out rate) && rate > 0) {
- this.rate = rate;
- break;
+ int n = 0;
+ if (rate == 0 && structure.get_int ("rate", out n)) {
+ rate = n;
+ }
+ if (channels == 0 && structure.get_int ("channels", out n)) {
+ channels = n;
+ }
+ if (depth == 0 && structure.get_int ("depth", out n)) {
+ depth = n;
}
}
@@ -138,14 +153,42 @@ namespace Spek {
private bool on_bus_watch (Bus bus, Message message) {
var structure = message.get_structure ();
- if (message.type == MessageType.ELEMENT && structure.get_name () == "spectrum") {
- var magnitudes = structure.get_value ("magnitude");
- for (int i = 0; i < bands; i++) {
- values[i] = magnitudes.list_get_value (i).get_float ();
+ switch (message.type ) {
+ case MessageType.ELEMENT:
+ if (structure.get_name () == "spectrum") {
+ var magnitudes = structure.get_value ("magnitude");
+ for (int i = 0; i < bands; i++) {
+ values[i] = magnitudes.list_get_value (i).get_float ();
+ }
+ data_cb (sample++, values);
}
- callback (sample++, values);
+ break;
+ case MessageType.TAG:
+ TagList tag_list;
+ message.parse_tag (out tag_list);
+ tag_list.foreach (on_tag);
+ break;
}
return true;
}
+
+ private void on_tag (TagList tag_list, string tag) {
+ switch (tag) {
+ case TAG_AUDIO_CODEC:
+ string s = null;
+ if (audio_codec == null && tag_list.get_string (tag, out s)) {
+ audio_codec = s;
+ info_cb ();
+ }
+ break;
+ case TAG_BITRATE:
+ uint u = 0;
+ if (bitrate == 0 && tag_list.get_uint (tag, out u)) {
+ bitrate = u;
+ info_cb ();
+ }
+ break;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/spek-spectrogram.vala b/src/spek-spectrogram.vala
@@ -25,6 +25,7 @@ namespace Spek {
public string file_name { get; private set; }
private Source source;
+ private string info;
private const int THRESHOLD = -92;
private const int BANDS = 1024;
@@ -52,6 +53,7 @@ namespace Spek {
public void open (string file_name) {
this.file_name = file_name;
+ this.info = "";
start ();
}
@@ -72,7 +74,7 @@ namespace Spek {
int samples = allocation.width - LPAD - RPAD;
if (samples > 0) {
image = new ImageSurface (Format.RGB24, samples, BANDS);
- source = new Source (file_name, BANDS, samples, THRESHOLD, source_callback);
+ source = new Source (file_name, BANDS, samples, THRESHOLD, data_cb, info_cb);
} else {
image = null;
source = null;
@@ -88,7 +90,7 @@ namespace Spek {
}
}
- private void source_callback (int sample, float[] values) {
+ private void data_cb (int sample, float[] values) {
for (int y = 0; y < values.length; y++) {
var level = double.min (
1.0, Math.log10 (1.0 - THRESHOLD + values[y]) / Math.log10 (-THRESHOLD));
@@ -97,6 +99,31 @@ namespace Spek {
queue_draw_area (LPAD + sample, TPAD, 1, allocation.height - TPAD - BPAD);
}
+ private void info_cb () {
+ string[] items = {};
+ if (source.audio_codec != null) {
+ items += source.audio_codec;
+ }
+ if (source.bitrate != 0) {
+ items += _("%d kbps").printf (source.bitrate / 1000);
+ }
+ if (source.rate != 0) {
+ items += _("%d Hz").printf (source.rate);
+ }
+ // Show sample rate only if there is no bitrate.
+ if (source.depth != 0 && source.bitrate == 0) {
+ items += _("%d bits").printf (source.depth);
+ }
+ if (source.channels != 0) {
+ items += ngettext ("%d channel", "%d channels", source.channels).
+ printf (source.channels);
+ }
+ if (items.length > 0) {
+ info = string.joinv (", ", items);
+ queue_draw_area (LPAD, 0, allocation.width - LPAD - RPAD, TPAD);
+ }
+ }
+
private override bool expose_event (EventExpose event) {
var cr = cairo_create (this.window);
@@ -160,7 +187,7 @@ namespace Spek {
// File properties.
cr.set_font_size (11.0);
cr.move_to (LPAD, TPAD - GAP);
- //cr.show_text (trim (cr, "MPEG 1 Audio, Layer 3 (MP3), 320 kbps, 44100 Hz, 2 channels", w - LPAD - RPAD, true));
+ cr.show_text (trim (cr, info, w - LPAD - RPAD, true));
FontExtents ext;
cr.font_extents (out ext);