2 * filter_audiochannels.c -- convert from one audio format to another
3 * Copyright (C) 2009 Ushodaya Enterprises Limited
4 * Author: Dan Dennedy <dan@dennedy.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <framework/mlt_filter.h>
22 #include <framework/mlt_frame.h>
23 #include <framework/mlt_log.h>
27 static int filter_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
29 // Used to return number of channels in the source
30 int channels_avail = *channels;
32 // Get the producer's audio
33 int error = mlt_frame_get_audio( frame, buffer, format, frequency, &channels_avail, samples );
34 if ( error ) return error;
36 if ( channels_avail < *channels )
38 int size = mlt_audio_format_size( *format, *samples, *channels );
39 int16_t *new_buffer = mlt_pool_alloc( size );
41 // Duplicate the existing channels
42 if ( *format == mlt_audio_s16 )
45 for ( i = 0; i < *samples; i++ )
47 for ( j = 0; j < *channels; j++ )
49 new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + k ];
50 k = ( k + 1 ) % channels_avail;
57 int size_avail = mlt_audio_format_size( *format, *samples, channels_avail );
58 int32_t *p = (int32_t*) new_buffer;
59 int i = *channels / channels_avail;
62 memcpy( p, *buffer, size_avail );
63 p += size_avail / sizeof(*p);
65 i = *channels % channels_avail;
68 size_avail = mlt_audio_format_size( *format, *samples, i );
69 memcpy( p, *buffer, size_avail );
72 // Update the audio buffer now - destroys the old
73 mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
76 else if ( channels_avail > *channels )
78 int size = mlt_audio_format_size( *format, *samples, *channels );
79 int16_t *new_buffer = mlt_pool_alloc( size );
81 // Drop all but the first *channels
82 if ( *format == mlt_audio_s16 )
85 for ( i = 0; i < *samples; i++ )
86 for ( j = 0; j < *channels; j++ )
87 new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + j ];
92 memcpy( new_buffer, *buffer, size );
94 // Update the audio buffer now - destroys the old
95 mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
101 /** Filter processing.
104 static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
106 mlt_frame_push_audio( frame, filter_get_audio );
110 /** Constructor for the filter.
113 mlt_filter filter_audiochannels_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
115 mlt_filter filter = mlt_filter_new();
117 filter->process = filter_process;