1 /*
2  * filter_audiochannels.c -- convert from one audio format to another
3  * Copyright (C) 2009-2014 Meltytech, LLC
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 
20 #include <framework/mlt_filter.h>
21 #include <framework/mlt_frame.h>
22 #include <framework/mlt_log.h>
23 
24 #include <string.h>
25 
filter_get_audio(mlt_frame frame,void ** buffer,mlt_audio_format * format,int * frequency,int * channels,int * samples)26 static int filter_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
27 {
28 	// Used to return number of channels in the source
29 	int channels_avail = *channels;
30 
31 	// Get the producer's audio
32 	int error = mlt_frame_get_audio( frame, buffer, format, frequency, &channels_avail, samples );
33 	if ( error ) return error;
34 
35 	if ( channels_avail < *channels )
36 	{
37 		int size = mlt_audio_format_size( *format, *samples, *channels );
38 		int16_t *new_buffer = mlt_pool_alloc( size );
39 
40 		// Duplicate the existing channels
41 		if ( *format == mlt_audio_s16 )
42 		{
43 			int i, j, k = 0;
44 			for ( i = 0; i < *samples; i++ )
45 			{
46 				for ( j = 0; j < *channels; j++ )
47 				{
48 					new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + k ];
49 					k = ( k + 1 ) % channels_avail;
50 				}
51 			}
52 		}
53 		else if ( *format == mlt_audio_s32le || *format == mlt_audio_f32le )
54 		{
55 			int32_t *p = (int32_t*) new_buffer;
56 			int i, j, k = 0;
57 			for ( i = 0; i < *samples; i++ )
58 			{
59 				for ( j = 0; j < *channels; j++ )
60 				{
61 					p[ ( i * *channels ) + j ] = ((int32_t*)(*buffer))[ ( i * channels_avail ) + k ];
62 					k = ( k + 1 ) % channels_avail;
63 				}
64 			}
65 		}
66 		else if ( *format == mlt_audio_u8 )
67 		{
68 			uint8_t *p = (uint8_t*) new_buffer;
69 			int i, j, k = 0;
70 			for ( i = 0; i < *samples; i++ )
71 			{
72 				for ( j = 0; j < *channels; j++ )
73 				{
74 					p[ ( i * *channels ) + j ] = ((uint8_t*)(*buffer))[ ( i * channels_avail ) + k ];
75 					k = ( k + 1 ) % channels_avail;
76 				}
77 			}
78 		}
79 		else
80 		{
81 			// non-interleaved - s32 or float
82 			int size_avail = mlt_audio_format_size( *format, *samples, channels_avail );
83 			int32_t *p = (int32_t*) new_buffer;
84 			int i = *channels / channels_avail;
85 			while ( i-- )
86 			{
87 				memcpy( p, *buffer, size_avail );
88 				p += size_avail / sizeof(*p);
89 			}
90 			i = *channels % channels_avail;
91 			if ( i )
92 			{
93 				size_avail = mlt_audio_format_size( *format, *samples, i );
94 				memcpy( p, *buffer, size_avail );
95 			}
96 		}
97 		// Update the audio buffer now - destroys the old
98 		mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
99 		*buffer = new_buffer;
100 	}
101 	else if ( channels_avail == 6 && *channels == 2 )
102 	{
103 		// Downmix 5.1 audio to stereo.
104 		// Mix levels taken from ATSC A/52 assuming maximum center and surround
105 		// mix levels.
106 		#define MIX(front, center, surr) (front + (0.707 * center) + (0.5 * surr))
107 
108 		// Convert to a supported format if necessary
109 		mlt_audio_format new_format = *format;
110 		switch( *format )
111 		{
112 		default:
113 			// Unknown. Try to convert to float anyway.
114 			mlt_log_error( NULL, "[audiochannels] Unknown format %d\n", *format );
115 		case mlt_audio_float:
116 		case mlt_audio_f32le:
117 			new_format = mlt_audio_float;
118 			break;
119 		case mlt_audio_s32le:
120 		case mlt_audio_s32:
121 			new_format = mlt_audio_s32;
122 			break;
123 		case mlt_audio_s16:
124 		case mlt_audio_u8:
125 			new_format = mlt_audio_s16;
126 			break;
127 		case mlt_audio_none:
128 			new_format = mlt_audio_none;
129 			break;
130 		}
131 		if ( *format != new_format && frame->convert_audio )
132 			frame->convert_audio( frame, buffer, format, new_format );
133 
134 		// Perform the downmix. Operate on the buffer in place to avoid realloc.
135 		if ( *format == mlt_audio_s16 )
136 		{
137 			int16_t* in = *buffer;
138 			int16_t* out = *buffer;
139 			int i;
140 			for ( i = 0; i < *samples; i++ )
141 			{
142 				float fl = in[0];
143 				float fr = in[1];
144 				float c = in[2];
145 				// in[3] is LFE
146 				float sl = in[4];
147 				float sr = in[5];
148 				*out++ = CLAMP( MIX(fl, c, sl), INT16_MIN, INT16_MAX ); // Left
149 				*out++ = CLAMP( MIX(fr, c, sr), INT16_MIN, INT16_MAX ); // Right
150 				in +=6;
151 			}
152 		}
153 		else if ( *format == mlt_audio_s32 )
154 		{
155 			int32_t* flin = *buffer;
156 			int32_t* frin = *buffer + (*samples * sizeof(float));
157 			int32_t* cin  = *buffer + (2 * *samples * sizeof(float));
158 			int32_t* slin = *buffer + (4 * *samples * sizeof(float));
159 			int32_t* srin = *buffer + (5 * *samples * sizeof(float));
160 			int32_t* lout = *buffer;
161 			int32_t* rout = *buffer + (*samples * sizeof(float));
162 			int i;
163 			for ( i = 0; i < *samples; i++ )
164 			{
165 				double fl = *flin++;
166 				double fr = *frin++;
167 				double c = *cin++;
168 				double sl = *slin++;
169 				double sr = *srin++;
170 				*lout++ = CLAMP( MIX(fl, c, sl), INT32_MIN, INT32_MAX );
171 				*rout++ = CLAMP( MIX(fr, c, sr), INT32_MIN, INT32_MAX );
172 			}
173 		}
174 		else if ( *format == mlt_audio_float )
175 		{
176 			float* flin = *buffer;
177 			float* frin = *buffer + (*samples * sizeof(float));
178 			float* cin  = *buffer + (2 * *samples * sizeof(float));
179 			float* slin = *buffer + (4 * *samples * sizeof(float));
180 			float* srin = *buffer + (5 * *samples * sizeof(float));
181 			float* lout = *buffer;
182 			float* rout = *buffer + (*samples * sizeof(float));
183 			int i;
184 			for ( i = 0; i < *samples; i++ )
185 			{
186 				float fl = *flin++;
187 				float fr = *frin++;
188 				float c = *cin++;
189 				float sl = *slin++;
190 				float sr = *srin++;
191 				*lout++ = MIX(fl, c, sl);
192 				*rout++ = MIX(fr, c, sr);
193 			}
194 		}
195 		else
196 		{
197 			mlt_log_error( NULL, "[audiochannels] Unable to mix format %d\n", *format );
198 		}
199 	}
200 	else if ( channels_avail > *channels )
201 	{
202 		int size = mlt_audio_format_size( *format, *samples, *channels );
203 		int16_t *new_buffer = mlt_pool_alloc( size );
204 		int i, j;
205 
206 		// Drop all but the first *channels
207 		if ( *format == mlt_audio_s16 )
208 		{
209 			for ( i = 0; i < *samples; i++ )
210 				for ( j = 0; j < *channels; j++ )
211 					new_buffer[ ( i * *channels ) + j ]	= ((int16_t*)(*buffer))[ ( i * channels_avail ) + j ];
212 		}
213 		else if ( *format == mlt_audio_s32le || *format == mlt_audio_f32le )
214 		{
215 			int32_t *p = (int32_t*) new_buffer;
216 			for ( i = 0; i < *samples; i++ )
217 				for ( j = 0; j < *channels; j++ )
218 					p[ ( i * *channels ) + j ]	= ((int32_t*)(*buffer))[ ( i * channels_avail ) + j ];
219 		}
220 		else if ( *format == mlt_audio_u8 )
221 		{
222 			uint8_t *p = (uint8_t*) new_buffer;
223 			for ( i = 0; i < *samples; i++ )
224 				for ( j = 0; j < *channels; j++ )
225 					p[ ( i * *channels ) + j ]	= ((uint8_t*)(*buffer))[ ( i * channels_avail ) + j ];
226 		}
227 		else
228 		{
229 			// non-interleaved - s32 or float
230 			memcpy( new_buffer, *buffer, size );
231 		}
232 		// Update the audio buffer now - destroys the old
233 		mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
234 		*buffer = new_buffer;
235 	}
236 	return error;
237 }
238 
239 /** Filter processing.
240 */
241 
filter_process(mlt_filter filter,mlt_frame frame)242 static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
243 {
244 	mlt_frame_push_audio( frame, filter_get_audio );
245 	return frame;
246 }
247 
248 /** Constructor for the filter.
249 */
250 
filter_audiochannels_init(mlt_profile profile,mlt_service_type type,const char * id,char * arg)251 mlt_filter filter_audiochannels_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
252 {
253 	mlt_filter filter = mlt_filter_new();
254 	if ( filter )
255 		filter->process = filter_process;
256 	return filter;
257 }
258