marlin r1339 - trunk/marlin
- From: iain svn gnome org
- To: svn-commits-list gnome org
- Subject: marlin r1339 - trunk/marlin
- Date: Sat, 8 Nov 2008 00:35:25 +0000 (UTC)
Author: iain
Date: Sat Nov 8 00:35:25 2008
New Revision: 1339
URL: http://svn.gnome.org/viewvc/marlin?rev=1339&view=rev
Log:
Squashed commit of the following:
commit fc0f016ffe54437d0a7ba4bf02ad903ccf189765
Author: iain <iain gnome org>
Date: Sat Nov 8 00:32:08 2008 +0000
Make recording worky
commit e35b55363463c94cb0c2ffe0a2b126e6ecab29e4
Author: iain <iain gnome org>
Date: Wed Nov 5 00:58:39 2008 +0000
Add sample ratio handling to jack record
Modified:
trunk/marlin/marlin-jack-play.c
trunk/marlin/marlin-jack-record.c
Modified: trunk/marlin/marlin-jack-play.c
==============================================================================
--- trunk/marlin/marlin-jack-play.c (original)
+++ trunk/marlin/marlin-jack-play.c Sat Nov 8 00:35:25 2008
@@ -266,8 +266,7 @@
g_object_unref (priv->sample);
}
- priv->sample = sample;
- g_object_ref (priv->sample);
+ priv->sample = g_object_ref (sample);
g_object_get (G_OBJECT (priv->sample),
"channels", &priv->channels,
"sample_rate", &priv->sample_rate,
Modified: trunk/marlin/marlin-jack-record.c
==============================================================================
--- trunk/marlin/marlin-jack-record.c (original)
+++ trunk/marlin/marlin-jack-record.c Sat Nov 8 00:35:25 2008
@@ -53,7 +53,7 @@
MARLIN_JACK_RECORD_MODE_RECORDING
} MarlinJackRecordMode;
-#define DEFAULT_RB_SIZE 65536
+#define DEFAULT_RB_SIZE 262144
static const size_t frame_size = sizeof (jack_default_audio_sample_t);
struct _port_data {
@@ -62,12 +62,11 @@
MarlinChannel *channel; /* The channel associated with the port */
MarlinBlock *block_list, *bl_end;
- float *data;
- guint frames_in_data;
-
jack_port_t *record; /* The record port */
jack_ringbuffer_t *rb;
+ float *rb_buffer, *tmp_buffer, *data;
+ guint frames_in_data;
SRC_STATE *state;
@@ -86,7 +85,7 @@
guint channels;
- guint rate, jrate;
+ guint sample_rate, jack_rate;
double src_ratio;
struct _port_data **port_data;
@@ -96,6 +95,8 @@
G_DEFINE_TYPE (MarlinJackRecord, marlin_jack_record, MARLIN_JACK_TYPE);
+static long process_more_frames (gpointer userdata, float **data);
+
static void
free_ports (MarlinJackRecord *jack)
{
@@ -111,7 +112,13 @@
jack_ringbuffer_free (pd->rb);
}
+ g_free (pd->rb_buffer);
+ g_free (pd->tmp_buffer);
g_free (pd->data);
+
+ if (pd->state) {
+ src_delete (pd->state);
+ }
g_free (pd);
}
@@ -140,7 +147,6 @@
JackPortIsInput, 0);
g_free (name);
- pd->data = g_new0 (float, MARLIN_BLOCK_SIZE);
priv->port_data[i] = pd;
}
}
@@ -171,7 +177,7 @@
}
if (priv->sample) {
- g_signal_handler_disconnect (priv->sample,
+ g_signal_handler_disconnect (priv->sample,
priv->sample_notify_id);
priv->sample_notify_id = 0;
g_object_unref (priv->sample);
@@ -181,20 +187,37 @@
((GObjectClass *) marlin_jack_record_parent_class)->dispose (object);
}
+static double
+calculate_rate_ratio (guint src_rate,
+ guint dest_rate)
+{
+ double ratio;
+
+ if (src_rate == 0) {
+ return 1.0;
+ }
+
+ ratio = (1.0 * dest_rate) / src_rate;
+ if (src_is_valid_ratio (ratio) == FALSE) {
+ ratio = 1.0;
+ }
+
+ return ratio;
+}
+
static void
sample_changed (GObject *object,
GParamSpec *pspec,
MarlinJackRecord *jack)
{
-#if 0
MarlinJackRecordPrivate *priv = jack->priv;
if (strcmp (pspec->name, "sample_rate") == 0) {
g_object_get (object,
- "sample_rate", &priv->rate,
+ "sample_rate", &priv->sample_rate,
NULL);
- priv->src_ratio = calculate_rate_ratio (priv->rate,
- priv->jrate);
+ priv->src_ratio = calculate_rate_ratio (priv->sample_rate,
+ priv->jack_rate);
return;
}
@@ -206,7 +229,6 @@
setup_ports (jack);
return;
}
-#endif
}
static void
@@ -224,13 +246,19 @@
g_object_unref (priv->sample);
}
- priv->sample = sample;
- g_object_ref (priv->sample);
+ priv->sample = g_object_ref (sample);
+ g_object_get (G_OBJECT (priv->sample),
+ "channels", &priv->channels,
+ "sample_rate", &priv->sample_rate,
+ NULL);
priv->sample_notify_id = g_signal_connect (priv->sample, "notify",
G_CALLBACK (sample_changed),
jack);
+ priv->src_ratio = calculate_rate_ratio (priv->sample_rate,
+ priv->jack_rate);
+
setup_ports ((MarlinJackRecord *) jack);
}
@@ -257,6 +285,7 @@
if (jack_ringbuffer_write (pd->rb, (void *) i_buf,
bytes_avail) < bytes_avail) {
/* Not sure what to do with this... signal? */
+ g_print ("xrun...\n");
overruns++;
}
}
@@ -271,6 +300,7 @@
switch (priv->mode) {
case MARLIN_JACK_RECORD_MODE_RECORDING:
+ case MARLIN_JACK_RECORD_MODE_PREROLLING:
process_recording (jack, nframes);
break;
@@ -312,6 +342,28 @@
}
}
+static long
+process_more_frames (gpointer userdata,
+ float **data)
+{
+ struct _port_data *pd = userdata;
+ MarlinJackRecord *jack = pd->jack;
+ size_t bytes_avail;
+
+ /* We want to put as much into the SRC as possible */
+ bytes_avail = jack_ringbuffer_read_space (pd->rb);
+ if (bytes_avail == 0) {
+ return 0;
+ }
+
+ jack_ringbuffer_read (pd->rb, (char *) pd->tmp_buffer, bytes_avail);
+
+ fprintf (stderr, "Got more frames: %d [%p]\n", bytes_avail / sizeof (float), pd);
+
+ *data = pd->tmp_buffer;
+ return bytes_avail / sizeof (float);
+}
+
/* Reader function: Reads data from the ringbuffer and puts it in the sample */
static gboolean
process_reader (gpointer data)
@@ -327,46 +379,65 @@
for (i = 0; i < 2; i++) {
struct _port_data *pd = priv->port_data[i];
- size_t bytes_avail;
guint frames;
+ long frames_needed;
+ size_t bytes_avail;
bytes_avail = jack_ringbuffer_read_space (pd->rb);
- frames = bytes_avail / frame_size;
+ /* Roll until we've got half the ringbuffer filled */
+ if (bytes_avail < DEFAULT_RB_SIZE / 2) {
+ g_print ("Got %d bytes, rolling\n", bytes_avail);
+ return TRUE;
+ }
+ g_print ("Starting: %p\n", pd);
+ frames_needed = MIN (MARLIN_BLOCK_SIZE - pd->frames_in_data,
+ (bytes_avail / sizeof (float)) / 8);
+ g_print ("Frames needed [%p] - %d (%d, %d)\n", pd, frames_needed, MARLIN_BLOCK_SIZE - pd->frames_in_data, (bytes_avail / sizeof (float)) / 8);
+
+ if (frames_needed == 0) {
+ continue;
+ }
+
+ frames = src_callback_read (pd->state, priv->src_ratio,
+ frames_needed, pd->rb_buffer);
+ g_print ("Got %d frames\n", frames);
if (frames == 0) {
continue;
}
+ fprintf (stderr, "Bing got %d frames\n", frames);
/* The amount of frames available will be fill a block */
- if (pd->frames_in_data + frames > MARLIN_BLOCK_SIZE) {
+ if (pd->frames_in_data + frames >= MARLIN_BLOCK_SIZE) {
guint32 needed, remain;
float *fd;
needed = MARLIN_BLOCK_SIZE - pd->frames_in_data;
remain = frames - needed;
+ fprintf (stderr, "Needed: %d - remains: %d\n", needed, remain);
/* Read from the ringbuffer into the next free space
in the frame buffer */
fd = pd->data + pd->frames_in_data;
- jack_ringbuffer_read (pd->rb, (char *) fd,
- needed * sizeof (float));
+ memcpy (fd, pd->rb_buffer, needed * sizeof (float));
/* Now we have a whole block, we can store it */
- store_block (jack, pd, pd->data, MARLIN_BLOCK_SIZE);
+ store_block (jack, pd, pd->data,
+ MARLIN_BLOCK_SIZE);
memset (pd->data, 0,
MARLIN_BLOCK_SIZE * sizeof (float));
if (remain > 0) {
- jack_ringbuffer_read (pd->rb, (char *) pd->data,
- remain * sizeof (float));
+ memcpy (pd->data, pd->rb_buffer + needed,
+ remain * sizeof (float));
}
pd->frames_in_data = remain;
} else {
float *fd;
fd = pd->data + pd->frames_in_data;
- jack_ringbuffer_read (pd->rb, (char *) fd, bytes_avail);
+ memcpy (fd, pd->rb_buffer, frames * sizeof (float));
pd->frames_in_data += frames;
}
}
@@ -383,7 +454,9 @@
MarlinJackRecord *jack = data;
MarlinJackRecordPrivate *priv = jack->priv;
- priv->jrate = nframes;
+ priv->jack_rate = nframes;
+ priv->src_ratio = calculate_rate_ratio (priv->sample_rate,
+ priv->jack_rate);
return 0;
}
@@ -440,6 +513,7 @@
for (i = 0; i < 2; i++) {
struct _port_data *pd = priv->port_data[i];
+ int err;
if (ports[i] == NULL) {
return FALSE;
@@ -457,17 +531,28 @@
return FALSE;
}
- pd->rb = jack_ringbuffer_create (frame_size * DEFAULT_RB_SIZE);
pd->channel = marlin_sample_get_channel (priv->sample, i);
+ pd->rb = jack_ringbuffer_create (frame_size * DEFAULT_RB_SIZE);
+
+ pd->rb_buffer = g_new (float, DEFAULT_RB_SIZE);
+ pd->tmp_buffer = g_new (float, DEFAULT_RB_SIZE);
+ pd->data = g_new (float, MARLIN_BLOCK_SIZE);
+
+ pd->state = src_callback_new (process_more_frames,
+ SRC_SINC_BEST_QUALITY,
+ 1, &err, pd);
}
free (ports);
- priv->mode = MARLIN_JACK_RECORD_MODE_RECORDING;
+ priv->mode = MARLIN_JACK_RECORD_MODE_PREROLLING;
- /* Start an idle function to read from the ringbuffer and write data
- to a sample */
- priv->reader_id = g_idle_add (process_reader, jack);
+ /* Start an timeout to read from the ringbuffer and write data
+ to a sample, don't really care about how fast this happens
+ the important thing is not to starve the writer process:
+ really the balance is between this timeout and the size of the
+ ringbuffer */
+ priv->reader_id = g_timeout_add (250, process_reader, jack);
return TRUE;
}
@@ -601,7 +686,7 @@
priv->jack_buf = g_new0 (jack_default_audio_sample_t, priv->bufsize * 16);
jack_set_sample_rate_callback (priv->client, srate_changed, jack);
- priv->jrate = jack_get_sample_rate (priv->client);
+ priv->jack_rate = jack_get_sample_rate (priv->client);
return jack;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]