marlin r1357 - in trunk: marlin po src
- From: iain svn gnome org
- To: svn-commits-list gnome org
- Subject: marlin r1357 - in trunk: marlin po src
- Date: Mon, 16 Feb 2009 00:55:25 +0000 (UTC)
Author: iain
Date: Mon Feb 16 00:55:24 2009
New Revision: 1357
URL: http://svn.gnome.org/viewvc/marlin?rev=1357&view=rev
Log:
Squashed commit of the following:
commit 41826f5da3e88cc5641361caf97376cc5f6bd3db
Author: Iain Holmes <iain openedhand com mailto:iain openedhand com>
Date: Mon Feb 16 00:53:17 2009 +0000
Set the Normalize menu item name correctly, depending on whether or not
there is a selection
commit 6e37e5cc36d72934ec4613b30607e6f3e19a41ab
Author: Iain Holmes <iain openedhand com mailto:iain openedhand com>
Date: Mon Feb 16 00:51:23 2009 +0000
Add the normalize menu item and hook it up
commit fd35e4d37e5d339ecd763f8eb9b2a7792c24a3f6
Author: Iain Holmes <iain openedhand com mailto:iain openedhand com>
Date: Mon Feb 16 00:29:27 2009 +0000
Fix some problems with marlin_channel_normalize and add MarlinSample function
commit feac65b4d642543ff606b5fbf8e16c373bc36cab
Author: Iain Holmes <iain openedhand com mailto:iain openedhand com>
Date: Sun Feb 15 23:04:44 2009 +0000
Add a normal channel function
Modified:
trunk/marlin/marlin-channel.c
trunk/marlin/marlin-channel.h
trunk/marlin/marlin-sample.c
trunk/marlin/marlin-sample.h
trunk/po/Makefile.in.in
trunk/src/marlin-window-menu.c
trunk/src/marlin-window.c
trunk/src/marlin.xml
Modified: trunk/marlin/marlin-channel.c
==============================================================================
--- trunk/marlin/marlin-channel.c (original)
+++ trunk/marlin/marlin-channel.c Mon Feb 16 00:55:24 2009
@@ -2,7 +2,7 @@
/*
* Authors: Iain Holmes <iain gnome org>
*
- * Copyright 2002-2007 Iain Holmes
+ * Copyright 2002-2009 Iain Holmes
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU Library General Public
@@ -71,7 +71,7 @@
* sample:
* filename:
* error:
- *
+ *
* Creates a new channel for @sample, using @filename as the basename for its
* temp files.
*
@@ -83,16 +83,16 @@
{
MarlinChannel *channel;
char *basename, *name;
-
+
channel = g_new0 (MarlinChannel, 1);
channel->lock = marlin_read_write_lock_new ();
basename = g_path_get_basename (filename);
name = g_strdup_printf ("%s/%s.XXXXXX",
- marlin_get_tmp_dir (),
+ marlin_get_tmp_dir (),
basename);
g_free (basename);
-
+
channel->frame_file = marlin_file_new (name, error);
g_free (name);
@@ -104,10 +104,10 @@
basename = g_path_get_basename (channel->frame_file->filename);
name = g_strdup_printf ("%s/%s.XXXXXX",
- marlin_get_tmp_dir (),
+ marlin_get_tmp_dir (),
basename);
g_free (basename);
-
+
channel->peak_file = marlin_file_new (name, error);
g_free (name);
@@ -154,7 +154,7 @@
WRITE_UNLOCK (channel->lock);
marlin_read_write_lock_destroy (channel->lock);
-
+
g_free (channel);
}
@@ -169,14 +169,14 @@
MarlinBlock *
marlin_channel_create_block (MarlinChannel *channel)
{
- return marlin_block_new (channel, channel->frame_file,
+ return marlin_block_new (channel, channel->frame_file,
channel->peak_file);
}
/* Implements an LRU paging system */
/* Max number of blocks that can be mapped for each channel
Each page is about 2meg of data */
-#define MAX_PAGE_COUNT 10
+#define MAX_PAGE_COUNT 10
/* define this to turn off the paging system to simplify testing
of the block/channel manipulation code. */
@@ -189,7 +189,7 @@
*
* Adds @block to the LRU cache for @channel or if it is already in
* the cache it is moved to the start of the queue. If there isn't room
- * in the cache then the block at the end of the queue is removed and
+ * in the cache then the block at the end of the queue is removed and
* unmapped.
*
* The channel must be write locked.
@@ -226,7 +226,7 @@
goto try_again;
}
}
-
+
g_queue_push_head (channel->pages, block);
#endif
marlin_block_map (block, NULL);
@@ -293,7 +293,7 @@
b = channel->last;
READ_UNLOCK (channel->lock);
-
+
return b;
}
@@ -305,11 +305,11 @@
return b;
}
-
+
block = lockless_get_for_frame (channel->first, frame);
READ_UNLOCK (channel->lock);
-
+
return block;
}
@@ -333,7 +333,7 @@
first = lockless_get_for_frame (channel->first, split_frame);
g_return_if_fail (first != NULL);
-
+
if (split_frame != first->start) {
second = marlin_block_split (first, split_frame);
@@ -343,7 +343,7 @@
first->next = second;
second->previous = first;
second->next = NULL;
-
+
/* If first->next was NULL,
then first was the last block
Set the channel last point to second */
@@ -369,7 +369,7 @@
guint64 split_frame)
{
g_return_if_fail (channel != NULL);
-
+
WRITE_LOCK (channel->lock);
lockless_split_block (channel, split_frame);
WRITE_UNLOCK (channel->lock);
@@ -428,7 +428,7 @@
{
struct _unlink_closure *c = data;
MarlinBlock *b;
-
+
WRITE_LOCK (c->channel->lock);
lockless_unlink_range (c->channel, c->start_frame, c->end_frame,
&b, NULL);
@@ -760,7 +760,7 @@
}
/* Splits the block on the insert_frame, so insert_frame will be first in
- new block. Then it gets the block for insert_frame - 1, and then inserts
+ new block. Then it gets the block for insert_frame - 1, and then inserts
data */
static gboolean
lockless_insert_data (MarlinChannel *channel,
@@ -1489,6 +1489,8 @@
return ret;
}
+/* FIXME: Might be useful to have a fixed ratio version so that we don't
+ have to make functions that just return the same number all the time */
static gboolean
lockless_channel_multiply (MarlinChannel *channel,
guint64 start,
@@ -1567,11 +1569,11 @@
* Returns: TRUE on success, FALSE on failure with details in @error.
*/
gboolean
-marlin_channel_invert (MarlinChannel *channel,
- guint64 start,
- guint64 finish,
+marlin_channel_invert (MarlinChannel *channel,
+ guint64 start,
+ guint64 finish,
MarlinUndoContext *ctxt,
- GError **error)
+ GError **error)
{
gboolean ret;
g_return_val_if_fail (channel != NULL, FALSE);
@@ -1660,14 +1662,14 @@
* Returns: TRUE on success, FALSE on failure with details in @error.
*/
gboolean
-marlin_channel_fade (MarlinChannel *channel,
- guint64 start,
- guint64 finish,
- MarlinFadeFunc fade_func,
- gpointer closure,
- MarlinOperation *operation,
+marlin_channel_fade (MarlinChannel *channel,
+ guint64 start,
+ guint64 finish,
+ MarlinFadeFunc fade_func,
+ gpointer closure,
+ MarlinOperation *operation,
MarlinUndoContext *ctxt,
- GError **error)
+ GError **error)
{
gboolean ret;
@@ -1744,9 +1746,9 @@
frames_needed = (src_range->finish - src_range->start) + 1;
src_block = lockless_get_for_frame (src->first, src_range->start);
-
+
/* Unlink all the blocks in dest we're going to replace */
- lockless_unlink_range (dest, dest_range->start, dest_range->finish,
+ lockless_unlink_range (dest, dest_range->start, dest_range->finish,
&dest_block, ctxt);
d = dest_block;
@@ -1767,11 +1769,11 @@
frames_avail = MIN (frames_needed, MARLIN_BLOCK_SIZE);
s_length = marlin_block_get_buffer (src_block, src_buf,
- src_start,
+ src_start,
frames_avail,
&s_next);
if (dest_block != NULL) {
- d_length = marlin_block_get_buffer (dest_block,
+ d_length = marlin_block_get_buffer (dest_block,
dest_buf,
dest_start,
frames_avail,
@@ -1782,10 +1784,10 @@
/* Apply the fades to the buffers */
for (i = 0; i < s_length; i++) {
- src_buf[i] = src_buf[i] * src_fade_func
+ src_buf[i] = src_buf[i] * src_fade_func
(frame_start + i, src_closure);
if (i < d_length) {
- dest_buf[i] = dest_buf[i] * dest_fade_func
+ dest_buf[i] = dest_buf[i] * dest_fade_func
(frame_start + i, dest_closure);
}
@@ -1849,7 +1851,7 @@
*/
guint64
marlin_channel_next_zero (MarlinChannel *channel,
- guint64 position)
+ guint64 position)
{
MarlinBlock *block;
float *data;
@@ -2304,3 +2306,91 @@
return ret;
}
+
+struct _normalize_closure {
+ float ratio;
+};
+
+static float
+normalize_func (guint64 position,
+ gpointer data)
+{
+ struct _normalize_closure *vc = data;
+ return vc->ratio;
+}
+
+gboolean
+marlin_channel_normalize (MarlinChannel *channel,
+ MarlinRange *range,
+ double db,
+ MarlinOperation *operation,
+ MarlinUndoContext *ctxt,
+ GError **error)
+{
+ struct _normalize_closure *nc;
+ double max_peak = 0.0;
+ double level = 1.0;
+ guint64 peak_range;
+ MarlinBlock *block;
+ MarlinPeak *peak_data;
+ guint64 start, end;
+ guint64 i, o;
+ float *buf;
+ gboolean ret = FALSE;
+
+ WRITE_LOCK (channel->lock);
+
+ block = lockless_get_for_frame (channel->first, range->start);
+ READ_LOCK (block->lock);
+
+ peak_data = marlin_block_get_peak_data (block);
+
+ start = range->start / MARLIN_FRAMES_PER_PEAK;
+ end = range->finish / MARLIN_FRAMES_PER_PEAK;
+ peak_range = start - end;
+
+ for (i = 0, o = start; i < peak_range; i++, o++) {
+ guint64 peak_in_channel;
+ MarlinPeak p;
+
+ peak_in_channel = block->start + (o * MARLIN_FRAMES_PER_PEAK);
+ if (peak_in_channel >= channel->frames) {
+ break;
+ }
+
+ if (peak_in_channel > block->end) {
+ /* Next block */
+ READ_UNLOCK (block->lock);
+
+ block = marlin_block_next (block);
+ g_assert (block != NULL);
+
+ READ_LOCK (block->lock);
+ o = 0;
+ peak_data = marlin_block_get_peak_data (block);
+ }
+
+ p = peak_data[o];
+
+ max_peak = MAX (max_peak, ((double) p.high / 256.0));
+ }
+
+ READ_UNLOCK (block->lock);
+
+ if (db == MARLIN_INFINITE_DB) {
+ level = 0.0;
+ } else {
+ level = pow (10.0, db / 10.0);
+ }
+
+ nc = g_new (struct _normalize_closure, 1);
+ nc->ratio = level / max_peak;
+
+ ret = lockless_channel_multiply (channel, range->start, range->finish,
+ normalize_func, nc, ctxt, error);
+ g_free (nc);
+
+ WRITE_UNLOCK (channel->lock);
+
+ return ret;
+}
Modified: trunk/marlin/marlin-channel.h
==============================================================================
--- trunk/marlin/marlin-channel.h (original)
+++ trunk/marlin/marlin-channel.h Mon Feb 16 00:55:24 2009
@@ -202,4 +202,10 @@
gboolean marlin_channel_is_ready (MarlinChannel *channel);
+gboolean marlin_channel_normalize (MarlinChannel *channel,
+ MarlinRange *range,
+ double db,
+ MarlinOperation *operation,
+ MarlinUndoContext *ctxt,
+ GError **error);
#endif
Modified: trunk/marlin/marlin-sample.c
==============================================================================
--- trunk/marlin/marlin-sample.c (original)
+++ trunk/marlin/marlin-sample.c Mon Feb 16 00:55:24 2009
@@ -1487,7 +1487,7 @@
marlin_undo_context_add (ctxt, u);
WRITE_LOCK (sample->priv->lock);
-
+
switch (range->coverage) {
case MARLIN_COVERAGE_BOTH:
for (i = 0; i < sample->priv->channels; i++) {
@@ -1501,7 +1501,7 @@
case MARLIN_COVERAGE_LEFT:
ret = marlin_channel_invert (sample->priv->channel_data->pdata[0],
- range->start, range->finish,
+ range->start, range->finish,
ctxt, error);
if (ret == FALSE) {
WRITE_UNLOCK (sample->priv->lock);
@@ -1517,7 +1517,7 @@
return FALSE;
}
ret = marlin_channel_invert (sample->priv->channel_data->pdata[1],
- range->start, range->finish,
+ range->start, range->finish,
ctxt, error);
if (ret == FALSE) {
WRITE_UNLOCK (sample->priv->lock);
@@ -1545,7 +1545,7 @@
struct _sample_closure *c = data;
g_object_set (G_OBJECT (c->sample),
- "dirty", TRUE,
+ "dirty", TRUE,
NULL);
marlin_sample_data_changed (c->sample, &(c->range));
}
@@ -1592,7 +1592,7 @@
adjust_volume_undo,
adjust_volume_destroy,
c);
-
+
marlin_undo_context_add (ctxt, u);
WRITE_LOCK (sample->priv->lock);
@@ -1627,7 +1627,7 @@
}
ret = marlin_channel_adjust_volume (sample->priv->channel_data->pdata[1], db, range->start, range->finish, ctxt, error);
-
+
if (ret == FALSE) {
WRITE_UNLOCK (sample->priv->lock);
return FALSE;
@@ -1714,7 +1714,7 @@
for (i = 0; i < sample->priv->channels; i++) {
ret = marlin_channel_insert_silence (sample->priv->channel_data->pdata[i],
- operation, position,
+ operation, position,
length, ctxt, error);
if (ret == FALSE) {
WRITE_UNLOCK (sample->priv->lock);
@@ -1763,13 +1763,14 @@
/* The newly added channel is always the second one */
channel = c->sample->priv->channel_data->pdata[1];
- ret = marlin_channel_copy_data (c->channel, channel, 0, c->channel->frames - 1, NULL);
+ ret = marlin_channel_copy_data (c->channel, channel, 0,
+ c->channel->frames - 1, NULL);
if (ret == FALSE) {
g_warning ("marlin_channel_copy_data failed");
}
g_object_set (G_OBJECT (c->sample),
- "dirty", TRUE,
+ "dirty", TRUE,
NULL);
}
@@ -1978,8 +1979,8 @@
src = sample->priv->channel_data->pdata[MARLIN_CHANNEL_LEFT];
/* Fill the new channel with 0 data */
- ret = marlin_channel_insert_silence (sample->priv->channel_data->pdata[MARLIN_CHANNEL_RIGHT],
- operation, (guint64) 0,
+ ret = marlin_channel_insert_silence (sample->priv->channel_data->pdata[MARLIN_CHANNEL_RIGHT],
+ operation, (guint64) 0,
src->frames, NULL, error);
if (ret == FALSE) {
WRITE_UNLOCK (sample->priv->lock);
@@ -1996,10 +1997,10 @@
}
} else {
MarlinChannel *src, *dest;
-
+
src = sample->priv->channel_data->pdata[MARLIN_CHANNEL_LEFT];
dest = sample->priv->channel_data->pdata[MARLIN_CHANNEL_RIGHT];
-
+
ret = marlin_channel_copy_data (src, dest, (guint64) 0, src->frames - 1, error);
WRITE_UNLOCK (sample->priv->lock);
@@ -2053,7 +2054,7 @@
*
* Splits @sample into many smaller #MarlinSample objects with the ranges of
* these samples taken from marker positions of @sample.
- *
+ *
* Return value: A GList containing #MarlinSamples.
*/
GList *
@@ -2081,7 +2082,7 @@
g_warning ("marlin_sample_new_from_sample_with_range failed");
return NULL;
}
-
+
samples = g_list_prepend (samples, ns);
g_object_set (G_OBJECT (ns),
@@ -2134,7 +2135,7 @@
} else {
float m;
- /*
+ /*
y = mx+c
x = (position - fade_start)
c = fade->in_level
@@ -2180,7 +2181,7 @@
int i;
g_return_val_if_fail (IS_MARLIN_SAMPLE (sample), FALSE);
-
+
c = g_new (struct _sample_closure, 1);
c->sample = sample;
c->range.start = fade->fade_start;
@@ -2194,11 +2195,11 @@
marlin_undo_context_add (ctxt, u);
WRITE_LOCK (sample->priv->lock);
-
+
for (i = 0; i < sample->priv->channels; i++) {
ret = marlin_channel_fade (sample->priv->channel_data->pdata[i],
fade->fade_start, fade->fade_end,
- (MarlinFadeFunc) sample_fade_func,
+ (MarlinFadeFunc) sample_fade_func,
fade, operation, ctxt, error);
if (ret == FALSE) {
WRITE_UNLOCK (sample->priv->lock);
@@ -2208,7 +2209,7 @@
WRITE_UNLOCK (sample->priv->lock);
g_object_set (G_OBJECT (sample),
- "dirty", TRUE,
+ "dirty", TRUE,
NULL);
marlin_sample_data_changed (sample, &c->range);
@@ -2281,12 +2282,12 @@
if (ctxt) {
c = g_new (struct _sample_closure, 1);
c->sample = dest;
-
+
u = marlin_undoable_new (crossfade_undo,
NULL,
crossfade_destroy,
c);
-
+
marlin_undo_context_add (ctxt, u);
}
@@ -2306,7 +2307,7 @@
(MarlinFadeFunc) sample_fade_func,
src_fade,
(MarlinFadeFunc) sample_fade_func,
- dest_fade, operation,
+ dest_fade, operation,
ctxt, error);
if (ret == FALSE) {
@@ -2315,7 +2316,7 @@
return FALSE;
}
}
-
+
WRITE_UNLOCK (dest_priv->lock);
READ_UNLOCK (src_priv->lock);
@@ -2324,7 +2325,7 @@
crossfade_undo,
NULL,
c);
-
+
marlin_undo_context_add (ctxt, u);
}
@@ -2375,7 +2376,7 @@
READ_LOCK (src->priv->lock);
WRITE_LOCK (dest->priv->lock);
-
+
/* create undoable */
fpms = (float) dest->priv->sample_rate / 1000.0f;
@@ -2421,16 +2422,16 @@
MarlinSamplePrivate *priv = sample->priv;
guint64 pos, new_pos;
int i;
-
+
g_return_val_if_fail (IS_MARLIN_SAMPLE (sample), position);
-
+
switch (coverage) {
case MARLIN_COVERAGE_BOTH:
pos = position;
for (i = 0; i < priv->channels; i++) {
new_pos = marlin_channel_next_zero (priv->channel_data->pdata[i],
position);
-
+
if (pos == position) {
pos = new_pos;
} else {
@@ -2454,7 +2455,7 @@
pos = position;
break;
}
-
+
return pos;
}
@@ -2463,7 +2464,7 @@
* @sample: A #MarlinSample to search
* @position: Start position of the search
* @coverage: Coverage of the search
- *
+ *
* Find the previous zer0 crossing before @position
*
* Return value: The previous position or @position if it is the first.
@@ -2664,18 +2665,18 @@
int i;
g_return_val_if_fail (sample != NULL, FALSE);
-
+
priv = sample->priv;
if (ctxt) {
c = g_new (struct _sample_closure, 1);
c->sample = sample;
-
+
u = marlin_undoable_new (expand_range_undo,
NULL,
expand_range_destroy,
c);
-
+
marlin_undo_context_add (ctxt, u);
}
@@ -2686,12 +2687,12 @@
soundtouch = marlin_soundtouch_new ();
marlin_soundtouch_set_channels (soundtouch, 1);
marlin_soundtouch_set_sample_rate (soundtouch, priv->sample_rate);
- marlin_soundtouch_set_tempo (soundtouch,
+ marlin_soundtouch_set_tempo (soundtouch,
((float)old_length) / (float)new_length);
for (i = 0; i < priv->channels; i++) {
- ret = marlin_channel_expand_range (priv->channel_data->pdata[i],
- soundtouch, range->start,
- range->finish, new_length,
+ ret = marlin_channel_expand_range (priv->channel_data->pdata[i],
+ soundtouch, range->start,
+ range->finish, new_length,
operation, ctxt, error);
if (ret) {
/* FIXME: We should pop off the last undoable
@@ -2710,7 +2711,7 @@
expand_range_undo,
NULL,
c);
-
+
marlin_undo_context_add (ctxt, u);
}
@@ -2771,7 +2772,7 @@
g_return_val_if_fail (src != NULL, FALSE);
g_return_val_if_fail (dest != NULL, FALSE);
-
+
src_priv = src->priv;
dest_priv = dest->priv;
@@ -2798,12 +2799,12 @@
if (ctxt) {
c = g_new (struct _sample_closure, 1);
c->sample = dest;
-
+
u = marlin_undoable_new (expand_mix_undo,
NULL,
expand_mix_destroy,
c);
-
+
marlin_undo_context_add (ctxt, u);
}
@@ -2815,11 +2816,11 @@
marlin_soundtouch_set_sample_rate (soundtouch, dest_priv->sample_rate);
for (i = 0; i < dest_priv->channels; i++) {
- ret = marlin_channel_expand_mix (src_priv->channel_data->pdata[i],
+ ret = marlin_channel_expand_mix (src_priv->channel_data->pdata[i],
dest_priv->channel_data->pdata[i],
- soundtouch,
- src_range->start,
- src_range->finish,
+ soundtouch,
+ src_range->start,
+ src_range->finish,
dest_range->start,
dest_range->finish,
src_db, dest_db,
@@ -2843,7 +2844,7 @@
expand_mix_undo,
NULL,
c);
-
+
marlin_undo_context_add (ctxt, u);
}
@@ -2858,7 +2859,124 @@
marlin_sample_data_changed (dest, dest_range);
- return TRUE;
+ return TRUE;
+}
+
+static void
+normalize_undo (gpointer data)
+{
+ struct _sample_closure *c = data;
+
+ g_object_set (G_OBJECT (c->sample),
+ "dirty", TRUE,
+ NULL);
+ marlin_sample_data_changed (c->sample, &(c->range));
+}
+
+static void
+normalize_destroy (gpointer data)
+{
+ g_free (data);
+}
+
+/**
+ * marlin_sample_normalize_range:
+ * @sample: A #MarlinSample
+ * @db: The volume to be set
+ * @range: A #MarlinRange
+ * @ctxt: A #MarlinUndoContext
+ * @error: A #GError
+ *
+ * Adjusts the volume of @sample to @db, within @range.
+ *
+ * Return value: TRUE on success, FALSE on failure with details in @error.
+ */
+gboolean
+marlin_sample_normalize_range (MarlinSample *sample,
+ float db,
+ MarlinRange *range,
+ MarlinUndoContext *ctxt,
+ GError **error)
+{
+ int i;
+ gboolean ret;
+ struct _sample_closure *c;
+ MarlinUndoable *u;
+
+ g_return_val_if_fail (IS_MARLIN_SAMPLE (sample), FALSE);
+
+ c = g_new (struct _sample_closure, 1);
+ c->sample = sample;
+ c->range.start = range->start;
+ c->range.finish = range->finish;
+ c->range.coverage = range->coverage;
+
+ u = marlin_undoable_new (normalize_undo,
+ normalize_undo,
+ normalize_destroy,
+ c);
+
+ marlin_undo_context_add (ctxt, u);
+
+ WRITE_LOCK (sample->priv->lock);
+
+ switch (range->coverage) {
+ case MARLIN_COVERAGE_BOTH:
+ for (i = 0; i < sample->priv->channels; i++) {
+ ret = marlin_channel_normalize
+ (sample->priv->channel_data->pdata[i],
+ range, db, NULL, ctxt, error);
+
+ if (ret == FALSE) {
+ WRITE_UNLOCK (sample->priv->lock);
+ return FALSE;
+ }
+ }
+ break;
+
+ case MARLIN_COVERAGE_LEFT:
+ ret = marlin_channel_normalize
+ (sample->priv->channel_data->pdata[0],
+ range, db, NULL, ctxt, error);
+
+ if (ret == FALSE) {
+ WRITE_UNLOCK (sample->priv->lock);
+ return FALSE;
+ }
+
+ break;
+
+ case MARLIN_COVERAGE_RIGHT:
+ if (sample->priv->channels != 2) {
+ g_warning ("Attempting to adjust volume on RIGHT in a mono sample.");
+ WRITE_UNLOCK (sample->priv->lock);
+ return FALSE;
+ }
+
+ ret = marlin_channel_normalize
+ (sample->priv->channel_data->pdata[1],
+ range, db, NULL, ctxt, error);
+
+ if (ret == FALSE) {
+ WRITE_UNLOCK (sample->priv->lock);
+ return FALSE;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ WRITE_UNLOCK (sample->priv->lock);
+
+ g_object_set (G_OBJECT (sample),
+ "dirty", TRUE,
+ NULL);
+
+ marlin_sample_data_changed (sample, range);
+
+ return TRUE;
}
/**
Modified: trunk/marlin/marlin-sample.h
==============================================================================
--- trunk/marlin/marlin-sample.h (original)
+++ trunk/marlin/marlin-sample.h Mon Feb 16 00:55:24 2009
@@ -75,9 +75,8 @@
and destination samples did
not match */
MARLIN_SAMPLE_ERROR_RATE_MISMATCH, /* Sample rate of the src and
- destination samples did not
+ destination samples did not
match */
-
} MarlinSampleError;
GType marlin_sample_get_type (void);
@@ -205,7 +204,11 @@
MarlinOperation *operation,
MarlinUndoContext *ctxt,
GError **error);
-
+gboolean marlin_sample_normalize_range (MarlinSample *sample,
+ float db,
+ MarlinRange *range,
+ MarlinUndoContext *ctxt,
+ GError **error);
void marlin_sample_read_lock (MarlinSample *sample);
void marlin_sample_read_unlock (MarlinSample *sample);
Modified: trunk/po/Makefile.in.in
==============================================================================
--- trunk/po/Makefile.in.in (original)
+++ trunk/po/Makefile.in.in Mon Feb 16 00:55:24 2009
@@ -56,7 +56,7 @@
PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; else echo "$(ALL_LINGUAS)"; fi)
-USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep ^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep ^$$lang$$`"; then printf "$$lang "; fi; done; fi)
+USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep '^$$lang$$' $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep '^$$lang$$'`"; then printf "$$lang "; fi; done; fi)
USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)" -o -n "$(LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done)
Modified: trunk/src/marlin-window-menu.c
==============================================================================
--- trunk/src/marlin-window-menu.c (original)
+++ trunk/src/marlin-window-menu.c Mon Feb 16 00:55:24 2009
@@ -2,7 +2,7 @@
/*
* Authors: Iain Holmes <iain gnome org>
*
- * Copyright 2002-2008 Iain Holmes
+ * Copyright 2002-2009 Iain Holmes
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public
@@ -422,14 +422,14 @@
MarlinSample *sample;
MarlinUndoManager *undo;
MarlinUndoContext *ctxt;
-
+
g_object_get (G_OBJECT (data),
"sample", &sample,
NULL);
undo = marlin_base_window_get_undo_manager (base);
ctxt = marlin_undo_manager_context_begin (undo, _("Select Nothing"));
-
+
marlin_window_select_none (MARLIN_WINDOW (data), ctxt);
marlin_undo_manager_context_end (undo, ctxt);
@@ -458,7 +458,7 @@
MarlinSample *sample;
MarlinUndoManager *undo;
MarlinUndoContext *ctxt;
-
+
g_object_get (G_OBJECT (data),
"sample", &sample,
NULL);
@@ -479,7 +479,7 @@
MarlinSample *sample;
MarlinUndoManager *undo;
MarlinUndoContext *ctxt;
-
+
g_object_get (G_OBJECT (data),
"sample", &sample,
NULL);
@@ -500,7 +500,7 @@
MarlinSample *sample;
MarlinUndoManager *undo;
MarlinUndoContext *ctxt;
-
+
g_object_get (G_OBJECT (data),
"sample", &sample,
NULL);
@@ -522,7 +522,7 @@
MarlinSample *sample;
MarlinUndoManager *undo;
MarlinUndoContext *ctxt;
-
+
g_object_get (G_OBJECT (data),
"sample", &sample,
NULL);
@@ -704,34 +704,41 @@
static void
process_adjust_volume (GtkAction *action,
- gpointer data)
+ gpointer data)
{
marlin_window_adjust_volume (MARLIN_WINDOW (data));
}
static void
+process_normalize (GtkAction *action,
+ MarlinWindow *window)
+{
+ marlin_window_normalize (window);
+}
+
+static void
process_insert_silence (GtkAction *action,
- gpointer data)
+ gpointer data)
{
marlin_window_insert_silence (MARLIN_WINDOW (data));
}
static void
process_change_channels (GtkAction *action,
- gpointer data)
+ gpointer data)
{
marlin_window_change_channels (MARLIN_WINDOW (data));
}
static void
process_split_sample (GtkAction *action,
- gpointer data)
+ gpointer data)
{
marlin_window_split_sample (MARLIN_WINDOW (data));
}
static void
-process_reverse_sample (GtkAction *action,
+process_reverse_sample (GtkAction *action,
MarlinWindow *window)
{
marlin_window_reverse_sample (window);
@@ -836,7 +843,7 @@
/* FIXME: All these displays should use the same gconf key,
and one place sets it and they all pay attention to it. */
static void
-scale_action_changed (GtkAction *action,
+scale_action_changed (GtkAction *action,
GtkRadioAction *current,
MarlinWindow *window)
{
@@ -1069,6 +1076,9 @@
{ "ProcessVolume", NULL, N_("Adjust Sample Volume..."), NULL,
N_("Adjust the volume of the sample"),
G_CALLBACK (process_adjust_volume) },
+ { "ProcessNormalize", NULL, N_("Normalize Sample Volume..."), NULL,
+ N_("Normalize the volume of the sample"),
+ G_CALLBACK (process_normalize) },
{ "ProcessInsertSilence", NULL, N_("Insert Silence..."), NULL,
N_("Insert silence into the sample"),
G_CALLBACK (process_insert_silence) },
Modified: trunk/src/marlin-window.c
==============================================================================
--- trunk/src/marlin-window.c (original)
+++ trunk/src/marlin-window.c Mon Feb 16 00:55:24 2009
@@ -2466,12 +2466,14 @@
set_path_name (ag, "ProcessInvert", _("Invert Sample"));
set_path_name (ag, "ProcessVolume", _("Adjust Sample Volume..."));
set_path_name (ag, "ProcessReverse", _("Reverse Sample"));
+ set_path_name (ag, "ProcessNormalize", _("Normalize Sample"));
} else {
/* Selection */
set_path_name (ag, "ProcessMute", _("Mute Selection"));
set_path_name (ag, "ProcessInvert", _("Invert Selection"));
set_path_name (ag, "ProcessVolume", _("Adjust Selection Volume..."));
set_path_name (ag, "ProcessReverse", _("Reverse Selection"));
+ set_path_name (ag, "ProcessNormalize", _("Normalize Selection"));
}
if (priv->sample) {
@@ -5496,14 +5498,14 @@
priv->edit_marker_dialog = marlin_edit_marker_dialog_new (MARLIN_BASE_WINDOW (window));
g_signal_connect (priv->edit_marker_dialog, "destroy",
- G_CALLBACK (gtk_widget_destroyed),
+ G_CALLBACK (gtk_widget_destroyed),
&priv->edit_marker_dialog);
gtk_widget_show (priv->edit_marker_dialog);
}
/**
* marlin_window_is_empty:
- * window: A #MarlinWindow object
+ * @window: A #MarlinWindow object
*
* Checks if @window has a sample loaded or not.
*
@@ -5524,3 +5526,43 @@
return (frames == 0);
}
+
+void
+marlin_window_normalize (MarlinWindow *window)
+{
+ MarlinWindowPrivate *priv = window->priv;
+ MarlinUndoContext *ctxt;
+ MarlinRange range;
+ gboolean ret;
+ GError *error = NULL;
+
+ marlin_sample_selection_get (priv->selection, &(range.coverage),
+ &(range.start), &(range.finish));
+ if (range.coverage == MARLIN_COVERAGE_NONE) {
+ guint64 frames;
+
+ /* Adjust whole sample */
+ g_object_get (G_OBJECT (priv->sample),
+ "total_frames", &frames,
+ NULL);
+ ctxt = marlin_undo_manager_context_begin (priv->undo,
+ _("Normalize Sample"));
+
+ range.coverage = MARLIN_COVERAGE_BOTH;
+ range.start = 0;
+ range.finish = frames - 1;
+ } else {
+ ctxt = marlin_undo_manager_context_begin (priv->undo,
+ _("Normalize Selection"));
+
+ }
+
+ ret = marlin_sample_normalize_range (priv->sample, 0.0,
+ &range, ctxt, &error);
+
+ if (ret == FALSE) {
+ g_warning ("marlin_sample_adjust_volume_range failed");
+ }
+
+ marlin_undo_manager_context_end (priv->undo, ctxt);
+}
Modified: trunk/src/marlin.xml
==============================================================================
--- trunk/src/marlin.xml (original)
+++ trunk/src/marlin.xml Mon Feb 16 00:55:24 2009
@@ -91,6 +91,7 @@
<menu name="ProcessMenu" action="Process">
<menuitem name="ProcessMute" action="ProcessMute"/>
<menuitem name="ProcessVolume" action="ProcessVolume"/>
+ <menuitem name="ProcessNormalize" action="ProcessNormalize"/>
<menuitem name="ProcessInsertSilence" action="ProcessInsertSilence"/>
<menuitem name="ProcessSwapMenu" action="ProcessSwapChannels"/>
<menuitem name="ProcessAdjustChannelsMenu" action="ProcessAdjustChannels"/>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]