]> git.sesse.net Git - mlt/blobdiff - src/modules/jackrack/filter_ladspa.c
Refactor audio conversion and mixing.
[mlt] / src / modules / jackrack / filter_ladspa.c
index 7eff6fab18569214bac84a51de069680c615dd51..02f427a0505a83323b0d84f40eea2ba11b3c9514 100644 (file)
 
 #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];
-       
+       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" );
+
        // Propogate these for the Jack processing callback
        mlt_properties_set_int( properties, "channels", channels );
 
        // Start JackRack
-       if ( mlt_properties_get( properties, "src" ) )
+       if ( resource )
        {
                // 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 );
+               jack_rack_open_file( jackrack, resource );
        }
+       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 );
@@ -84,51 +68,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;
+       LADSPA_Data **input_buffers  = mlt_pool_alloc( sizeof( LADSPA_Data* ) * *channels );
+       LADSPA_Data **output_buffers = mlt_pool_alloc( sizeof( LADSPA_Data* ) * *channels );
 
-       // 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;
-
-       // 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;
 }
 
 
@@ -137,6 +105,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 );
@@ -145,32 +114,6 @@ 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.
 */
 
@@ -180,11 +123,8 @@ mlt_filter filter_ladspa_init( mlt_profile profile, mlt_service_type type, const
        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 );
        }
        return this;
 }