]> git.sesse.net Git - mlt/blobdiff - src/modules/jackrack/filter_ladspa.c
Fix audio seeking when no first video pts available.
[mlt] / src / modules / jackrack / filter_ladspa.c
index b9b362dd62c8fde5d02e46598930bc44d0a9021b..88ba1d434c31b039cc2a770b3cc38dd1ae150ff4 100644 (file)
@@ -18,9 +18,9 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#include "filter_ladspa.h"
-
+#include <framework/mlt_filter.h>
 #include <framework/mlt_frame.h>
+#include <framework/mlt_log.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #define BUFFER_LEN 10000
 
-static void initialise_jack_rack( mlt_properties properties, int channels )
+static jack_rack_t* initialise_jack_rack( mlt_properties properties, int channels )
 {
-       int i;
-       char mlt_name[20];
-       
-       // Propogate these for the Jack processing callback
-       mlt_properties_set_int( properties, "channels", channels );
+       jack_rack_t *jackrack = NULL;
+       char *resource = mlt_properties_get( properties, "resource" );
+       if ( !resource && mlt_properties_get( properties, "src" ) )
+               resource = mlt_properties_get( properties, "src" );
 
        // Start JackRack
-       if ( mlt_properties_get( properties, "src" ) )
+       if ( resource || mlt_properties_get_int64( properties, "_pluginid" ) )
        {
                // Create JackRack without Jack client name so that it only uses LADSPA
-               jack_rack_t *jackrack = jack_rack_new( NULL, channels );
-               mlt_properties_set_data( properties, "jackrack", jackrack, 0, NULL, NULL );
-               jack_rack_open_file( jackrack, mlt_properties_get( properties, "src" ) );
-       }
-               
-       // Allocate buffers
-       LADSPA_Data **input_buffers = mlt_pool_alloc( sizeof( LADSPA_Data ) * channels );
-       LADSPA_Data **output_buffers = mlt_pool_alloc( sizeof( LADSPA_Data ) * channels );
-
-       // Set properties - released inside filter_close
-       mlt_properties_set_data( properties, "input_buffers", input_buffers, sizeof( LADSPA_Data *) * channels, NULL, NULL );
-       mlt_properties_set_data( properties, "output_buffers", output_buffers, sizeof( LADSPA_Data *) * channels, NULL, NULL );
-
-       // Register Jack ports
-       for ( i = 0; i < channels; i++ )
-       {
-               input_buffers[i] = mlt_pool_alloc( BUFFER_LEN * sizeof( LADSPA_Data ) );
-               snprintf( mlt_name, sizeof( mlt_name ), "ibuf%d", i );
-               mlt_properties_set_data( properties, mlt_name, input_buffers[i], BUFFER_LEN * sizeof( LADSPA_Data ), NULL, NULL );
-
-               output_buffers[i] = mlt_pool_alloc( BUFFER_LEN * sizeof( LADSPA_Data ) );
-               snprintf( mlt_name, sizeof( mlt_name ), "obuf%d", i );
-               mlt_properties_set_data( properties, mlt_name, output_buffers[i], BUFFER_LEN * sizeof( LADSPA_Data ), NULL, NULL );
+               jackrack = jack_rack_new( NULL, channels );
+               mlt_properties_set_data( properties, "jackrack", jackrack, 0,
+                       (mlt_destructor) jack_rack_destroy, NULL );
+
+               if ( resource )
+                       // Load JACK Rack XML file
+                       jack_rack_open_file( jackrack, resource );
+               else if ( mlt_properties_get_int64( properties, "_pluginid" ) )
+               {
+                       // Load one LADSPA plugin by its UniqueID
+                       unsigned long id = mlt_properties_get_int64( properties, "_pluginid" );
+                       plugin_desc_t *desc = plugin_mgr_get_any_desc( jackrack->plugin_mgr, id );
+                       plugin_t *plugin;
+                       if ( desc && ( plugin = jack_rack_instantiate_plugin( jackrack, desc ) ) )
+                       {
+                               // TODO: move this into get_audio when keyframing is ready
+                               LADSPA_Data value;
+                               int index, c;
+
+                               plugin->enabled = TRUE;
+                               for ( index = 0; index < desc->control_port_count; index++ )
+                               {
+                                       // Apply the control port values
+                                       char key[20];
+                                       value = plugin_desc_get_default_control_value( desc, index, sample_rate );
+                                       snprintf( key, sizeof(key), "%d", index );
+                                       if ( mlt_properties_get( properties, key ) )
+                                               value = mlt_properties_get_double( properties, key );
+                                       for ( c = 0; c < plugin->copies; c++ )
+                                               plugin->holders[c].control_memory[index] = value;
+                               }
+                               plugin->wet_dry_enabled = mlt_properties_get( properties, "wetness" ) != NULL;
+                               if ( plugin->wet_dry_enabled )
+                               {
+                                       value = mlt_properties_get_double( properties, "wetness" );
+                                       for ( c = 0; c < channels; c++ )
+                                               plugin->wet_dry_values[c] = value;
+                               }
+                               process_add_plugin( jackrack->procinfo, plugin );
+                       }
+                       else
+                               mlt_log_error( properties, "failed to load plugin %lu\n", id );
+               }
        }
+       return jackrack;
 }
 
 
 /** Get the audio.
 */
 
-static int ladspa_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
+static int ladspa_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
 {
        // Get the filter service
        mlt_filter filter = mlt_frame_pop_audio( frame );
@@ -85,51 +105,35 @@ static int ladspa_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format
        mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter );
 
        // Get the producer's audio
+       *format = mlt_audio_float;
        mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
        
        // Initialise LADSPA if needed
        jack_rack_t *jackrack = mlt_properties_get_data( filter_properties, "jackrack", NULL );
        if ( jackrack == NULL )
        {
-               sample_rate = *frequency;
-               initialise_jack_rack( filter_properties, *channels );
-               jackrack = mlt_properties_get_data( filter_properties, "jackrack", NULL );
+               sample_rate = *frequency; // global inside jack_rack
+               jackrack = initialise_jack_rack( filter_properties, *channels );
        }
                
        // Get the filter-specific properties
-       LADSPA_Data **input_buffers = mlt_properties_get_data( filter_properties, "input_buffers", NULL );
-       LADSPA_Data **output_buffers = mlt_properties_get_data( filter_properties, "output_buffers", NULL );
-       
-       // Process the audio
-       int16_t *q = *buffer;
-       int i, j;
-
-       // Convert to floats and write into output ringbuffer
-       for ( i = 0; i < *samples; i++ )
-               for ( j = 0; j < *channels; j++ )
-                       input_buffers[ j ][ i ] = ( float )( *q ++ ) / 32768.0;
+       LADSPA_Data **input_buffers  = mlt_pool_alloc( sizeof( LADSPA_Data* ) * *channels );
+       LADSPA_Data **output_buffers = mlt_pool_alloc( sizeof( LADSPA_Data* ) * *channels );
 
-       // Do LADSPA processing
-       if ( jackrack && process_ladspa( jackrack->procinfo, *samples, input_buffers, output_buffers) == 0 )
+       int i;
+       for ( i = 0; i < *channels; i++ )
        {
-               // Read from output buffer and convert from floats
-               q = *buffer;
-               for ( i = 0; i < *samples; i++ )
-                       for ( j = 0; j < *channels; j++ )
-                       {
-                               if ( output_buffers[ j ][ i ] > 1.0 )
-                                       output_buffers[ j ][ i ] = 1.0;
-                               else if ( output_buffers[ j ][ i ] < -1.0 )
-                                       output_buffers[ j ][ i ] = -1.0;
-                       
-                               if ( output_buffers[ j ][ i ] > 0 )
-                                       *q ++ = 32767 * output_buffers[ j ][ i ];
-                               else
-                                       *q ++ = 32768 * output_buffers[ j ][ i ];
-                       }
+               input_buffers[i]  = (LADSPA_Data*) *buffer + i * *samples;
+               output_buffers[i] = (LADSPA_Data*) *buffer + i * *samples;
        }
 
-       return 0;
+       // Do LADSPA processing
+       int error = jackrack && process_ladspa( jackrack->procinfo, *samples, input_buffers, output_buffers );
+
+       mlt_pool_release( input_buffers );
+       mlt_pool_release( output_buffers );
+
+       return error;
 }
 
 
@@ -138,6 +142,7 @@ static int ladspa_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format
 
 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
 {
+       if ( mlt_frame_is_test_audio( frame ) == 0 )
        {
                mlt_frame_push_audio( frame, this );
                mlt_frame_push_audio( frame, ladspa_get_audio );
@@ -146,46 +151,19 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
        return frame;
 }
 
-
-static void filter_close( mlt_filter this )
-{
-       int i;
-       char mlt_name[20];
-       mlt_properties properties = MLT_FILTER_PROPERTIES( this );
-       
-       if ( mlt_properties_get_data( properties, "jackrack", NULL ) != NULL )
-       {
-               for ( i = 0; i < mlt_properties_get_int( properties, "channels" ); i++ )
-               {
-                       snprintf( mlt_name, sizeof( mlt_name ), "obuf%d", i );
-                       mlt_pool_release( mlt_properties_get_data( properties, mlt_name, NULL ) );
-                       snprintf( mlt_name, sizeof( mlt_name ), "ibuf%d", i );
-                       mlt_pool_release( mlt_properties_get_data( properties, mlt_name, NULL ) );
-               }
-               mlt_pool_release( mlt_properties_get_data( properties, "output_buffers", NULL ) );
-               mlt_pool_release( mlt_properties_get_data( properties, "input_buffers", NULL ) );
-       
-               jack_rack_t *jackrack = mlt_properties_get_data( properties, "jackrack", NULL );
-               jack_rack_destroy( jackrack );
-       }       
-       this->parent.close = NULL;
-       mlt_service_close( &this->parent );
-}
-
 /** Constructor for the filter.
 */
 
-mlt_filter filter_ladspa_init( char *arg )
+mlt_filter filter_ladspa_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
 {
        mlt_filter this = mlt_filter_new( );
        if ( this != NULL )
        {
                mlt_properties properties = MLT_FILTER_PROPERTIES( this );
-               
                this->process = filter_process;
-               this->close = filter_close;
-               
-               mlt_properties_set( properties, "src", arg );
+               mlt_properties_set( properties, "resource", arg );
+               if ( !strncmp( id, "ladspa.", 7 ) )
+                       mlt_properties_set( properties, "_pluginid", id + 7 );
        }
        return this;
 }