* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include "filter_volume.h"
-
+#include <framework/mlt_filter.h>
#include <framework/mlt_frame.h>
#include <stdio.h>
j++;
}
}
- smoothed /= j;
+ if (j) smoothed /= j;
// fprintf( stderr, "smoothed over %d values, result %f\n", j, smoothed );
return smoothed;
/** Get the audio.
*/
-static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
+static int filter_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
{
- // Get the properties of the a frame
- mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
- double gain = mlt_properties_get_double( properties, "volume.gain" );
- double max_gain = mlt_properties_get_double( properties, "volume.max_gain" );
- double limiter_level = 0.5; /* -6 dBFS */
- int normalise = mlt_properties_get_int( properties, "volume.normalise" );
- double amplitude = mlt_properties_get_double( properties, "volume.amplitude" );
- int i, j;
- double sample;
- int16_t peak;
-
// Get the filter from the frame
- mlt_filter this = mlt_properties_get_data( properties, "filter_volume", NULL );
+ mlt_filter this = mlt_frame_pop_audio( frame );
// Get the properties from the filter
mlt_properties filter_props = MLT_FILTER_PROPERTIES( this );
- if ( mlt_properties_get( properties, "volume.limiter" ) != NULL )
- limiter_level = mlt_properties_get_double( properties, "volume.limiter" );
+ // Get the frame's filter instance properties
+ mlt_properties instance_props = mlt_frame_unique_properties( frame, MLT_FILTER_SERVICE( this ) );
+
+ // Get the parameters
+ double gain = mlt_properties_get_double( instance_props, "gain" );
+ double max_gain = mlt_properties_get_double( instance_props, "max_gain" );
+ double limiter_level = 0.5; /* -6 dBFS */
+ int normalise = mlt_properties_get_int( instance_props, "normalise" );
+ double amplitude = mlt_properties_get_double( instance_props, "amplitude" );
+ int i, j;
+ double sample;
+ int16_t peak;
+
+ if ( mlt_properties_get( instance_props, "limiter" ) != NULL )
+ limiter_level = mlt_properties_get_double( instance_props, "limiter" );
// Get the producer's audio
+ *format = mlt_audio_s16;
mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
// fprintf( stderr, "filter_volume: frequency %d\n", *frequency );
int samplemax = (1 << (bytes_per_samp * 8 - 1)) - 1;
int samplemin = -samplemax - 1;
+ mlt_service_lock( MLT_FILTER_SERVICE( this ) );
+
if ( normalise )
{
int window = mlt_properties_get_int( filter_props, "window" );
}
else
{
- gain *= amplitude / signal_max_power( *buffer, *channels, *samples, &peak );
+ gain *= amplitude / signal_max_power( (int16_t*) *buffer, *channels, *samples, &peak );
}
}
gain = max_gain;
// Initialise filter's previous gain value to prevent an inadvertant jump from 0
- if ( mlt_properties_get( filter_props, "previous_gain" ) == NULL )
- mlt_properties_set_double( filter_props, "previous_gain", gain );
+ mlt_position last_position = mlt_properties_get_position( filter_props, "_last_position" );
+ mlt_position current_position = mlt_frame_get_position( frame );
+ if ( mlt_properties_get( filter_props, "_previous_gain" ) == NULL
+ || current_position != last_position + 1 )
+ mlt_properties_set_double( filter_props, "_previous_gain", gain );
// Start the gain out at the previous
- double previous_gain = mlt_properties_get_double( filter_props, "previous_gain" );
+ double previous_gain = mlt_properties_get_double( filter_props, "_previous_gain" );
// Determine ramp increment
double gain_step = ( gain - previous_gain ) / *samples;
// fprintf( stderr, "filter_volume: previous gain %f current gain %f step %f\n", previous_gain, gain, gain_step );
// Save the current gain for the next iteration
- mlt_properties_set_double( filter_props, "previous_gain", gain );
+ mlt_properties_set_double( filter_props, "_previous_gain", gain );
+ mlt_properties_set_position( filter_props, "_last_position", current_position );
+
+ mlt_service_unlock( MLT_FILTER_SERVICE( this ) );
// Ramp from the previous gain to the current
gain = previous_gain;
- int16_t *p = *buffer;
+ int16_t *p = (int16_t*) *buffer;
// Apply the gain
for ( i = 0; i < *samples; i++ )
static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
{
- mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
mlt_properties filter_props = MLT_FILTER_PROPERTIES( this );
+ mlt_properties instance_props = mlt_frame_unique_properties( frame, MLT_FILTER_SERVICE( this ) );
+
+ double gain = 1.0; // no adjustment
// Parse the gain property
- if ( mlt_properties_get( properties, "gain" ) == NULL )
+ if ( mlt_properties_get( filter_props, "gain" ) != NULL )
{
- double gain = 1.0; // no adjustment
-
- if ( mlt_properties_get( filter_props, "gain" ) != NULL )
+ char *p = mlt_properties_get( filter_props, "gain" );
+
+ if ( strncaseeq( p, "normalise", 9 ) )
+ mlt_properties_set( filter_props, "normalise", "" );
+ else
{
- char *p = mlt_properties_get( filter_props, "gain" );
-
- if ( strncaseeq( p, "normalise", 9 ) )
- mlt_properties_set( filter_props, "normalise", "" );
+ if ( strcmp( p, "" ) != 0 )
+ gain = strtod( p, &p );
+
+ while ( isspace( *p ) )
+ p++;
+
+ /* check if "dB" is given after number */
+ if ( strncaseeq( p, "db", 2 ) )
+ gain = DBFSTOAMP( gain );
else
+ gain = fabs( gain );
+
+ // If there is an end adjust gain to the range
+ if ( mlt_properties_get( filter_props, "end" ) != NULL )
{
+ double end = -1;
+ char *p = mlt_properties_get( filter_props, "end" );
if ( strcmp( p, "" ) != 0 )
- gain = fabs( strtod( p, &p) );
+ end = strtod( p, &p );
while ( isspace( *p ) )
p++;
/* check if "dB" is given after number */
if ( strncaseeq( p, "db", 2 ) )
- gain = DBFSTOAMP( gain );
-
- // If there is an end adjust gain to the range
- if ( mlt_properties_get( filter_props, "end" ) != NULL )
- {
- // Determine the time position of this frame in the transition duration
- mlt_position in = mlt_filter_get_in( this );
- mlt_position out = mlt_filter_get_out( this );
- mlt_position time = mlt_frame_get_position( frame );
- double position = ( double )( time - in ) / ( double )( out - in + 1 );
-
- double end = -1;
- char *p = mlt_properties_get( filter_props, "end" );
- if ( strcmp( p, "" ) != 0 )
- end = fabs( strtod( p, &p) );
-
- while ( isspace( *p ) )
- p++;
-
- /* check if "dB" is given after number */
- if ( strncaseeq( p, "db", 2 ) )
- end = DBFSTOAMP( gain );
-
- if ( end != -1 )
- gain += ( end - gain ) * position;
- }
+ end = DBFSTOAMP( gain );
+ else
+ end = fabs( end );
+
+ if ( end != -1 )
+ gain += ( end - gain ) * mlt_filter_get_progress( this, frame );
}
}
- mlt_properties_set_double( properties, "volume.gain", gain );
}
+ mlt_properties_set_double( instance_props, "gain", gain );
// Parse the maximum gain property
if ( mlt_properties_get( filter_props, "max_gain" ) != NULL )
{
char *p = mlt_properties_get( filter_props, "max_gain" );
- double gain = fabs( strtod( p, &p) ); // 0 = no max
+ double gain = strtod( p, &p ); // 0 = no max
while ( isspace( *p ) )
p++;
/* check if "dB" is given after number */
if ( strncaseeq( p, "db", 2 ) )
gain = DBFSTOAMP( gain );
+ else
+ gain = fabs( gain );
- mlt_properties_set_double( properties, "volume.max_gain", gain );
+ mlt_properties_set_double( instance_props, "max_gain", gain );
}
// Parse the limiter property
if ( level < 0 )
level = -level;
}
- mlt_properties_set_double( properties, "volume.limiter", level );
+ mlt_properties_set_double( instance_props, "limiter", level );
}
// Parse the normalise property
// If there is an end adjust gain to the range
if ( mlt_properties_get( filter_props, "end" ) != NULL )
{
- // Determine the time position of this frame in the transition duration
- mlt_position in = mlt_filter_get_in( this );
- mlt_position out = mlt_filter_get_out( this );
- mlt_position time = mlt_frame_get_position( frame );
- double position = ( double )( time - in ) / ( double )( out - in + 1 );
- amplitude *= position;
+ amplitude *= mlt_filter_get_progress( this, frame );
}
- mlt_properties_set_int( properties, "volume.normalise", 1 );
- mlt_properties_set_double( properties, "volume.amplitude", amplitude );
+ mlt_properties_set_int( instance_props, "normalise", 1 );
+ mlt_properties_set_double( instance_props, "amplitude", amplitude );
}
// Parse the window property and allocate smoothing buffer if needed
mlt_properties_set_data( filter_props, "smooth_buffer", smooth_buffer, 0, free, NULL );
}
- // Put a filter reference onto the frame
- mlt_properties_set_data( properties, "filter_volume", this, 0, NULL, NULL );
+ // Push the filter onto the stack
+ mlt_frame_push_audio( frame, this );
// Override the get_audio method
mlt_frame_push_audio( frame, filter_get_audio );
/** Constructor for the filter.
*/
-mlt_filter filter_volume_init( char *arg )
+mlt_filter filter_volume_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
{
- mlt_filter this = calloc( sizeof( struct mlt_filter_s ), 1 );
+ mlt_filter this = calloc( 1, sizeof( struct mlt_filter_s ) );
if ( this != NULL && mlt_filter_init( this, NULL ) == 0 )
{
mlt_properties properties = MLT_FILTER_PROPERTIES( this );