Show stream info in the window (issue 7)

This commit is contained in:
Alexander Kojevnikov 2010-05-20 21:32:06 +10:00
parent 9db2524bdf
commit f46f1fc9ae
2 changed files with 86 additions and 16 deletions

View File

@ -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;
}
}
}
}

View File

@ -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);