Run pipeline in a separate thread

This commit is contained in:
Alexander Kojevnikov 2010-07-04 13:08:37 +10:00
parent 2e8355ee84
commit 00b385d6d7
3 changed files with 37 additions and 2 deletions

View File

@ -18,6 +18,7 @@ INCLUDES = \
-DPKGLIBDIR=\""$(pkglibdir)"\" -DPKGLIBDIR=\""$(pkglibdir)"\"
VALAFLAGS = \ VALAFLAGS = \
--thread \
--vapidir=$(srcdir)/../vapi \ --vapidir=$(srcdir)/../vapi \
--pkg config \ --pkg config \
--pkg spek-audio \ --pkg spek-audio \

View File

@ -42,6 +42,9 @@ namespace Spek {
private float[] input; private float[] input;
private float[] output; private float[] output;
private unowned Thread thread = null;
private bool quit = false;
public Pipeline (string file_name, int bands, int samples, int threshold, Callback cb) { public Pipeline (string file_name, int bands, int samples, int threshold, Callback cb) {
this.cx = new Audio.Context (file_name); this.cx = new Audio.Context (file_name);
this.bands = bands; this.bands = bands;
@ -85,7 +88,31 @@ namespace Spek {
this.cx.start (samples); this.cx.start (samples);
} }
~Pipeline () {
stop ();
}
public void start () { public void start () {
stop ();
try {
thread = Thread.create (thread_func, true);
thread.set_priority (ThreadPriority.LOW);
} catch (ThreadError e) {
assert_not_reached ();
}
}
public void stop () {
if (thread != null) {
quit = true;
thread.join ();
quit = false;
thread = null;
}
}
private void * thread_func () {
int pos = 0; int pos = 0;
int sample = 0; int sample = 0;
int64 frames = 0; int64 frames = 0;
@ -99,6 +126,9 @@ namespace Spek {
uint8 *buffer = (uint8 *) this.buffer; uint8 *buffer = (uint8 *) this.buffer;
var block_size = cx.width * cx.channels / 8; var block_size = cx.width * cx.channels / 8;
while (size >= block_size) { while (size >= block_size) {
if (quit) {
return null;
}
input[pos] = average_input (buffer); input[pos] = average_input (buffer);
buffer += block_size; buffer += block_size;
size -= block_size; size -= block_size;
@ -139,6 +169,9 @@ namespace Spek {
} }
cb (sample++, output); cb (sample++, output);
if (sample == samples) {
return null;
}
Posix.memset (output, 0, sizeof (float) * bands); Posix.memset (output, 0, sizeof (float) * bands);
frames = 0; frames = 0;
num_fft = 0; num_fft = 0;
@ -146,6 +179,7 @@ namespace Spek {
} }
assert (size == 0); assert (size == 0);
} }
return null;
} }
private float average_input (uint8 *buffer) { private float average_input (uint8 *buffer) {

View File

@ -74,7 +74,7 @@ namespace Spek {
private void start () { private void start () {
if (pipeline != null) { if (pipeline != null) {
// pipeline.stop (); pipeline.stop ();
} }
// The number of samples is the number of pixels available for the image. // The number of samples is the number of pixels available for the image.
@ -108,7 +108,7 @@ namespace Spek {
1.0, Math.log10 (1.0 - THRESHOLD + values[y]) / Math.log10 (-THRESHOLD)); 1.0, Math.log10 (1.0 - THRESHOLD + values[y]) / Math.log10 (-THRESHOLD));
put_pixel (image, sample, y, get_color (level)); put_pixel (image, sample, y, get_color (level));
} }
queue_draw_area (LPAD + sample, TPAD, 1, allocation.height - TPAD - BPAD); Idle.add (() => { queue_draw (); return false; });
} }
private override bool expose_event (EventExpose event) { private override bool expose_event (EventExpose event) {