|
|
@ -1,8 +1,6 @@
|
|
|
|
/* Author: Max Howell <max.howell@methylblue.com>, (C) 2004
|
|
|
|
/* Author: Max Howell <max.howell@methylblue.com>, (C) 2004
|
|
|
|
Copyright: See COPYING file that comes with this distribution */
|
|
|
|
Copyright: See COPYING file that comes with this distribution */
|
|
|
|
|
|
|
|
|
|
|
|
/* gcc doesn't like inline for me */
|
|
|
|
|
|
|
|
#define inline
|
|
|
|
|
|
|
|
/* need access to port_ticket */
|
|
|
|
/* need access to port_ticket */
|
|
|
|
#define XINE_ENGINE_INTERNAL
|
|
|
|
#define XINE_ENGINE_INTERNAL
|
|
|
|
|
|
|
|
|
|
|
@ -12,16 +10,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static MyNode theList;
|
|
|
|
static MyNode theList;
|
|
|
|
static metronom_t theMetronom;
|
|
|
|
|
|
|
|
static int myChannels = 0;
|
|
|
|
static int myChannels = 0;
|
|
|
|
|
|
|
|
static int64_t pts_per_smpls;
|
|
|
|
|
|
|
|
|
|
|
|
MyNode* const myList = &theList;
|
|
|
|
MyNode* const myList = &theList;
|
|
|
|
metronom_t* const myMetronom = &theMetronom;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* defined in xineEngine.cpp */
|
|
|
|
|
|
|
|
extern void _debug( const char * );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*************************
|
|
|
|
/*************************
|
|
|
|
* post plugin functions *
|
|
|
|
* post plugin functions *
|
|
|
@ -30,9 +22,7 @@ extern void _debug( const char * );
|
|
|
|
static int
|
|
|
|
static int
|
|
|
|
scope_port_open( xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode )
|
|
|
|
scope_port_open( xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
_debug( "scope_port_open()\n" );
|
|
|
|
post_audio_port_t *port = (post_audio_port_t *)port_gen;
|
|
|
|
|
|
|
|
|
|
|
|
#define port ((post_audio_port_t*)port_gen)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_x_post_rewire( (post_plugin_t*)port->post );
|
|
|
|
_x_post_rewire( (post_plugin_t*)port->post );
|
|
|
|
_x_post_inc_usage( port );
|
|
|
|
_x_post_inc_usage( port );
|
|
|
@ -44,13 +34,20 @@ scope_port_open( xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bi
|
|
|
|
|
|
|
|
|
|
|
|
myChannels = _x_ao_mode2channels( mode );
|
|
|
|
myChannels = _x_ao_mode2channels( mode );
|
|
|
|
|
|
|
|
|
|
|
|
return port->original_port->open( port->original_port, stream, bits, rate, mode );
|
|
|
|
int ret = port->original_port->open( port->original_port, stream, bits, rate, mode );
|
|
|
|
|
|
|
|
#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \
|
|
|
|
|
|
|
|
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
|
|
|
|
|
|
|
|
pts_per_smpls = ((uint32_t)90000 * (uint32_t)32768) / rate;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
pts_per_smpls = stream->metronom->pts_per_smpls;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
scope_port_close( xine_audio_port_t *port_gen, xine_stream_t *stream )
|
|
|
|
scope_port_close( xine_audio_port_t *port_gen, xine_stream_t *stream )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
_debug( "scope_port_close()\n" );
|
|
|
|
post_audio_port_t *port = (post_audio_port_t *)port_gen;
|
|
|
|
|
|
|
|
|
|
|
|
port->stream = NULL;
|
|
|
|
port->stream = NULL;
|
|
|
|
port->original_port->close( port->original_port, stream );
|
|
|
|
port->original_port->close( port->original_port, stream );
|
|
|
@ -61,28 +58,29 @@ scope_port_close( xine_audio_port_t *port_gen, xine_stream_t *stream )
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
scope_port_put_buffer( xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream )
|
|
|
|
scope_port_put_buffer( xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
#if XINE_MAJOR_VERSION < 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION < 2) || \
|
|
|
|
post_audio_port_t *port = (post_audio_port_t *)port_gen;
|
|
|
|
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION < 10)
|
|
|
|
|
|
|
|
MyNode *new_node;
|
|
|
|
|
|
|
|
const int num_samples = buf->num_frames * myChannels;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* we are too simple to handle 8bit */
|
|
|
|
/* we are too simple to handle 8bit */
|
|
|
|
/* what does it mean when stream == NULL? */
|
|
|
|
/* what does it mean when stream == NULL? */
|
|
|
|
if( port->bits == 8 ) {
|
|
|
|
if( port->bits == 8 ) {
|
|
|
|
port->original_port->put_buffer( port->original_port, buf, stream ); return; }
|
|
|
|
port->original_port->put_buffer( port->original_port, buf, stream ); return; }
|
|
|
|
|
|
|
|
|
|
|
|
/* I keep my own metronom because xine wouldn't for some reason */
|
|
|
|
MyNode *new_node;
|
|
|
|
memcpy( myMetronom, stream->metronom, sizeof(metronom_t) );
|
|
|
|
const int num_samples = buf->num_frames * myChannels;
|
|
|
|
|
|
|
|
|
|
|
|
new_node = malloc( sizeof(MyNode) );
|
|
|
|
new_node = malloc( sizeof(MyNode) );
|
|
|
|
new_node->vpts = myMetronom->got_audio_samples( myMetronom, buf->vpts, buf->num_frames );
|
|
|
|
#ifdef METRONOM_VPTS
|
|
|
|
|
|
|
|
new_node->vpts = stream->metronom->get_option(stream->metronom, METRONOM_VPTS);
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
new_node->vpts = stream->metronom->got_audio_samples( stream->metronom, 0, 0 );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
new_node->num_frames = buf->num_frames;
|
|
|
|
new_node->num_frames = buf->num_frames;
|
|
|
|
new_node->mem = malloc( num_samples * 2 );
|
|
|
|
new_node->mem = malloc( num_samples * 2 );
|
|
|
|
memcpy( new_node->mem, buf->mem, num_samples * 2 );
|
|
|
|
memcpy( new_node->mem, buf->mem, num_samples * 2 );
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int64_t
|
|
|
|
int64_t
|
|
|
|
K = myMetronom->pts_per_smpls; /*smpls = 1<<16 samples*/
|
|
|
|
K = pts_per_smpls; /*smpls = 1<<16 samples*/
|
|
|
|
K *= num_samples;
|
|
|
|
K *= num_samples;
|
|
|
|
K /= (1<<16);
|
|
|
|
K /= (1<<16);
|
|
|
|
K += new_node->vpts;
|
|
|
|
K += new_node->vpts;
|
|
|
@ -97,9 +95,6 @@ scope_port_put_buffer( xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_st
|
|
|
|
* NOTE this is thread-safe due to the way we handle the list in the GUI thread */
|
|
|
|
* NOTE this is thread-safe due to the way we handle the list in the GUI thread */
|
|
|
|
new_node->next = myList->next;
|
|
|
|
new_node->next = myList->next;
|
|
|
|
myList->next = new_node;
|
|
|
|
myList->next = new_node;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef port
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
@ -113,13 +108,17 @@ scope_dispose( post_plugin_t *this )
|
|
|
|
* plugin init function *
|
|
|
|
* plugin init function *
|
|
|
|
************************/
|
|
|
|
************************/
|
|
|
|
|
|
|
|
|
|
|
|
xine_post_t*
|
|
|
|
#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \
|
|
|
|
scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target )
|
|
|
|
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
|
|
|
|
|
|
|
|
static post_plugin_t* scope_plugin_new( post_class_t *class_gen, int inputs, xine_audio_port_t *audio_target[], xine_video_port_t *video_target[] )
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
xine_post_t* scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target )
|
|
|
|
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if( audio_target == NULL )
|
|
|
|
if( audio_target == NULL )
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
post_plugin_t *post_plugin = xine_xmalloc( sizeof(post_plugin_t) );
|
|
|
|
post_plugin_t *post_plugin = calloc( 1, sizeof(post_plugin_t) );
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
post_plugin_t *this = post_plugin;
|
|
|
|
post_plugin_t *this = post_plugin;
|
|
|
@ -129,7 +128,12 @@ scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target )
|
|
|
|
|
|
|
|
|
|
|
|
_x_post_init( this, 1, 0 );
|
|
|
|
_x_post_init( this, 1, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
port = _x_post_intercept_audio_port( this, audio_target, &input, &output );
|
|
|
|
#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \
|
|
|
|
|
|
|
|
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
|
|
|
|
|
|
|
|
port = _x_post_intercept_audio_port( post_plugin, audio_target[0], &input, &output );
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
port = _x_post_intercept_audio_port( post_plugin, audio_target, &input, &output );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
port->new_port.open = scope_port_open;
|
|
|
|
port->new_port.open = scope_port_open;
|
|
|
|
port->new_port.close = scope_port_close;
|
|
|
|
port->new_port.close = scope_port_close;
|
|
|
|
port->new_port.put_buffer = scope_port_put_buffer;
|
|
|
|
port->new_port.put_buffer = scope_port_put_buffer;
|
|
|
@ -145,10 +149,46 @@ scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target )
|
|
|
|
/* code is straight from xine_init_post()
|
|
|
|
/* code is straight from xine_init_post()
|
|
|
|
can't use that function as it only dlopens the plugins
|
|
|
|
can't use that function as it only dlopens the plugins
|
|
|
|
and our plugin is statically linked in */
|
|
|
|
and our plugin is statically linked in */
|
|
|
|
|
|
|
|
|
|
|
|
post_plugin->running_ticket = xine->port_ticket;
|
|
|
|
post_plugin->running_ticket = xine->port_ticket;
|
|
|
|
post_plugin->xine = xine;
|
|
|
|
post_plugin->xine = xine;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \
|
|
|
|
|
|
|
|
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
|
|
|
|
|
|
|
|
return post_plugin;
|
|
|
|
|
|
|
|
#else
|
|
|
|
return &post_plugin->xine_post;
|
|
|
|
return &post_plugin->xine_post;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int64_t scope_plugin_pts_per_smpls( void *post )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return pts_per_smpls;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \
|
|
|
|
|
|
|
|
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
|
|
|
|
|
|
|
|
static void *scope_init_plugin(xine_t *xine, const void *data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
static const post_class_t post_scope_class = {
|
|
|
|
|
|
|
|
.open_plugin = scope_plugin_new,
|
|
|
|
|
|
|
|
.identifier = "codeine-scope",
|
|
|
|
|
|
|
|
.description = "Codeine Scope",
|
|
|
|
|
|
|
|
.dispose = NULL,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(void)xine;
|
|
|
|
|
|
|
|
(void)data;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (void*)&post_scope_class;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const post_info_t scope_special_info = {
|
|
|
|
|
|
|
|
.type = XINE_POST_TYPE_AUDIO_VISUALIZATION,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const plugin_info_t scope_plugin_info[] = {
|
|
|
|
|
|
|
|
{ PLUGIN_POST, 10, "codeine-scope", XINE_VERSION_CODE, &scope_special_info, scope_init_plugin },
|
|
|
|
|
|
|
|
{ PLUGIN_NONE, 0, NULL, 0, NULL, NULL }
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|