]> git.sesse.net Git - mlt/blob - src/modules/core/filter_audiochannels.c
A little debugging.
[mlt] / src / modules / core / filter_audiochannels.c
1 /*
2  * filter_audiochannels.c -- convert from one audio format to another
3  * Copyright (C) 2009-2012 Ushodaya Enterprises Limited
4  * Author: Dan Dennedy <dan@dennedy.org>
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <framework/mlt_filter.h>
22 #include <framework/mlt_frame.h>
23 #include <framework/mlt_log.h>
24
25 #include <string.h>
26
27 static int filter_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
28 {
29         // Used to return number of channels in the source
30         int channels_avail = *channels;
31
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;
35
36         if ( channels_avail < *channels )
37         {
38                 int size = mlt_audio_format_size( *format, *samples, *channels );
39                 int16_t *new_buffer = mlt_pool_alloc( size );
40
41                 // Duplicate the existing channels
42                 if ( *format == mlt_audio_s16 )
43                 {
44                         int i, j, k = 0;
45                         for ( i = 0; i < *samples; i++ )
46                         {
47                                 for ( j = 0; j < *channels; j++ )
48                                 {
49                                         new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + k ];
50                                         k = ( k + 1 ) % channels_avail;
51                                 }
52                         }
53                 }
54                 else if ( *format == mlt_audio_s32le || *format == mlt_audio_f32le )
55                 {
56                         int32_t *p = (int32_t*) new_buffer;
57                         int i, j, k = 0;
58                         for ( i = 0; i < *samples; i++ )
59                         {
60                                 for ( j = 0; j < *channels; j++ )
61                                 {
62                                         p[ ( i * *channels ) + j ] = ((int32_t*)(*buffer))[ ( i * channels_avail ) + k ];
63                                         k = ( k + 1 ) % channels_avail;
64                                 }
65                         }
66                 }
67                 else if ( *format == mlt_audio_u8 )
68                 {
69                         uint8_t *p = (uint8_t*) new_buffer;
70                         int i, j, k = 0;
71                         for ( i = 0; i < *samples; i++ )
72                         {
73                                 for ( j = 0; j < *channels; j++ )
74                                 {
75                                         p[ ( i * *channels ) + j ] = ((uint8_t*)(*buffer))[ ( i * channels_avail ) + k ];
76                                         k = ( k + 1 ) % channels_avail;
77                                 }
78                         }
79                 }
80                 else
81                 {
82                         // non-interleaved - s32 or float
83                         int size_avail = mlt_audio_format_size( *format, *samples, channels_avail );
84                         int32_t *p = (int32_t*) new_buffer;
85                         int i = *channels / channels_avail;
86                         while ( i-- )
87                         {
88                                 memcpy( p, *buffer, size_avail );
89                                 p += size_avail / sizeof(*p);
90                         }
91                         i = *channels % channels_avail;
92                         if ( i )
93                         {
94                                 size_avail = mlt_audio_format_size( *format, *samples, i );
95                                 memcpy( p, *buffer, size_avail );
96                         }
97                 }
98                 // Update the audio buffer now - destroys the old
99                 mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
100                 *buffer = new_buffer;
101         }
102         else if ( channels_avail > *channels )
103         {
104                 int size = mlt_audio_format_size( *format, *samples, *channels );
105                 int16_t *new_buffer = mlt_pool_alloc( size );
106
107                 // Drop all but the first *channels
108                 if ( *format == mlt_audio_s16 )
109                 {
110                         int i, j;
111                         for ( i = 0; i < *samples; i++ )
112                                 for ( j = 0; j < *channels; j++ )
113                                         new_buffer[ ( i * *channels ) + j ]     = ((int16_t*)(*buffer))[ ( i * channels_avail ) + j ];
114                 }
115                 else
116                 {
117                         // non-interleaved
118                         memcpy( new_buffer, *buffer, size );
119                 }
120                 // Update the audio buffer now - destroys the old
121                 mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
122                 *buffer = new_buffer;
123         }
124         return error;
125 }
126
127 /** Filter processing.
128 */
129
130 static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
131 {
132         mlt_frame_push_audio( frame, filter_get_audio );
133         return frame;
134 }
135
136 /** Constructor for the filter.
137 */
138
139 mlt_filter filter_audiochannels_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
140 {
141         mlt_filter filter = mlt_filter_new();
142         if ( filter )
143                 filter->process = filter_process;
144         return filter;
145 }