Subject: [linux-audio-dev] EDL's ... in process
From: Paul Barton-Davis (pbd_AT_Op.Net)
Date: Wed Oct 18 2000 - 16:57:17 EEST
Well, OK, since nobody else was apparently going to do anything soon
about an EDL implementation, I've stepped up to the plate. I have
ported my original C++ implementation of a super-efficient EDL system
back to C, or more specifically, to glib, which many people seem
comfortable using for its lists and so forth.
Here is what the info at the top of .c file says:
/* This is a set of "objects"/"functions" designed to implement
extremely efficient editing of arbitarily sized data streams.
There are 3 layers to the model used here:
buffer_t: an abstract representation of some data stream.
It has 4 "methods" that can be called:
`item_size' will return the number of bytes per item
`item_count' will return the number of items
`copy_to' will copy a specified number of items
to a memory location provided by the caller
`copy_from' will copy a specified number of items
from a memory location provided by the caller.
It also has a `private_data' member, for use
in passing extra data to the functions that
are used for these `methods'.
Precisely what the items are, where they come
from, how they get here: this is all completely
irrelevant to the API. In addition, it is very
unlikely that any of these methods will ever
be used by the user; sequence_read() and
sequence_write() take care of this.
piece_t: describes a contiguous region within a buffer_t.
sequence_t: an ordered list of piece_t's that, taken together,
describes the current state of the data stream.
There are operations to insert in, delete and replace any part
of the data stream. AT NO TIME is the underlying data ever
modified in any way. Editing operations simply alter the
list of piece_t's making up a sequence. In fact, even the very
existence of ANY underlying data only matters when attempting to
read the data stream via sequence_read() or writing via
sequence_write().
A sequence_t also has infinite undo and redo capabilities. Every
time an editing (insert, delete, replace) operation is performed,
the state of the sequence_t is saved. The operation may be undone
with sequence_undo(); each time an operation is undone, it is also
put on the redo list, and may be redone with sequence_redo.
*/
Enclosed below is the current header file.
The C/glib implementation is at the same stage as the C++ one: a test
program demonstrates it working perfectly and intelligently on arrays
of char.
The next stage of development for this EDL model is to connect it to
GtkWaveForm, specifically, to create a new GTK+ class called
GtkEDLWaveBuffer that can be used to view waveforms described by an
EDL, and initiate editing operations on them.
I don't believe that this will take too long. After that, I intend to
have Ardour's Track objects and tape butler thread become EDL aware,
so that Ardour can play back edited audio streams.
I have embarked down this course because I have serious doubts about
the ability of any existing linux soundfile editor to handle
multichannel editing. It appears to far out of the design space that
its authors were working in, and although I am not certain of this,
the disk i/o management techniques needed to make it work properly are
seem to be missing from every editor i have looked at so far.
GtkWaveForm looks very promising, because of its excellent level of
abstraction.
If anyone has particular interests in seeing the development of a
working, GPL'ed EDL source base (in C) for Linux, please let me know,
and we can both pore over the source I have so far and find ways to
make it even faster and better. BTW, I can't say I really enjoyed
reverting to C, but its the right thing to do if this model is to be
useful to lots of people (which would be nice).
--p
/*
Copyright (C) 2000 Paul Barton-Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id$
*/
#ifndef __sequence_h__
#define __sequence_h__
#include <glib.h>
typedef struct _buffer {
guint32 (*item_size) (struct _buffer *self);
guint32 (*item_count) (struct _buffer *self);
/* The two copy methods take an index, `start' into the data, and
a count of how many data items are to be transferred to/from
`dst' or `src'. Each returns a count of how many items were
successfully transferred.
*/
guint32 (*copy_to) (struct _buffer *self, guchar *dst, guint32 start, guint32 cnt);
guint32 (*copy_from) (struct _buffer *self, guchar *src, guint32 start, guint32 cnt);
gpointer *private_data;
} buffer_t;
buffer_t * buffer_new (guint32 (*isz)(), guint32 (*icnt)(),
guint32 (*copyto)(buffer_t*, guchar *, guint32, guint32),
guint32 (*copyfrom)(buffer_t*, guchar *, guint32, guint32),
gpointer data);
typedef struct _piece
{
buffer_t *buffer;
guint32 start;
guint32 length;
} piece_t;
#define piece_size(p) ((p)->length * (p)->buffer->item_size (p->buffer))
piece_t *piece_new (buffer_t *b, guint32 start, guint32 cnt);
typedef struct _sequence_state {
GList *pieces;
guint32 length;
} sequence_state_t;
#define SEQUENCE_UNDO_STACK 0
#define SEQUENCE_REDO_STACK 1
typedef struct _sequence {
GList *pieces;
GList *stack[2];
guint32 length;
} sequence_t;
sequence_t *sequence_new ();
guint32 sequence_read (sequence_t *, guchar *buf, guint32 start, guint32 cnt);
guint32 sequence_write (sequence_t *, guchar *buf, guint32 start, guint32 cnt);
int sequence_insert_sequence (sequence_t *, guint32 where, sequence_t *);
int sequence_insert_piece (sequence_t *, guint32 where, piece_t *);
int sequence_delete (sequence_t *, guint32 start, guint32 length);
int sequence_replace_piece (sequence_t *, guint32 start, piece_t *);
int sequence_replace_sequence (sequence_t *, guint32 start, sequence_t *);
int sequence_undo (sequence_t *);
int sequence_redo (sequence_t *);
#endif /* __sequence_h__ */
This archive was generated by hypermail 2b28 : Wed Oct 18 2000 - 17:34:27 EEST