• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ** Copyright (C) 2020 Arthur Taylor <art@ified.ca>
3 ** Copyright (C) 2019 Erik de Castro Lopo <erikd@mega-nerd.com>
4 **
5 ** This program is free software ; you can redistribute it and/or modify
6 ** it under the terms of the GNU Lesser General Public License as published by
7 ** the Free Software Foundation ; either version 2.1 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program 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
13 ** GNU Lesser General Public License for more details.
14 **
15 ** You should have received a copy of the GNU Lesser General Public License
16 ** along with this program ; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 
20 #include	"sfconfig.h"
21 #include	"sndfile.h"
22 #include	"common.h"
23 #include	"mpeg.h"
24 
25 
26 #if HAVE_MPEG
27 
28 #include <lame/lame.h>
29 
30 /*
31  * RANT RANT RANT
32  *
33  * Lame has 11 functions for inputing sample data of various types and
34  * configurations, but due to bad definitions, or missing combinations, they
35  * aren't really of much help to us.
36  *
37  */
38 
39 typedef struct
40 {	lame_t lamef ;
41 	unsigned char *block ;
42 	size_t block_len ;
43 	int frame_samples ;
44 	double compression ;
45 	int initialized ;
46 } MPEG_L3_ENC_PRIVATE ;
47 
48 
49 /*-----------------------------------------------------------------------------------------------
50 ** Private function prototypes.
51 */
52 
53 static int mpeg_l3_encoder_close (SF_PRIVATE *psf) ;
54 static int mpeg_l3_encoder_construct (SF_PRIVATE *psf) ;
55 static int mpeg_l3_encoder_byterate (SF_PRIVATE *psf) ;
56 
57 static sf_count_t mpeg_l3_encode_write_short_stereo (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
58 static sf_count_t mpeg_l3_encode_write_int_stereo (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
59 static sf_count_t mpeg_l3_encode_write_float_stereo (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
60 static sf_count_t mpeg_l3_encode_write_double_stereo (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
61 static sf_count_t mpeg_l3_encode_write_short_mono (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
62 static sf_count_t mpeg_l3_encode_write_int_mono (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
63 static sf_count_t mpeg_l3_encode_write_float_mono (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
64 static sf_count_t mpeg_l3_encode_write_double_mono (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
65 
66 /*-----------------------------------------------------------------------------------------------
67 ** Exported functions.
68 */
69 
70 int
mpeg_l3_encoder_init(SF_PRIVATE * psf,int info_tag)71 mpeg_l3_encoder_init (SF_PRIVATE *psf, int info_tag)
72 {	MPEG_L3_ENC_PRIVATE* pmpeg = NULL ;
73 
74 	if (psf->file.mode == SFM_RDWR)
75 		return SFE_BAD_MODE_RW ;
76 
77 	if (psf->file.mode != SFM_WRITE)
78 		return SFE_INTERNAL ;
79 
80 	psf->codec_data = pmpeg = calloc (1, sizeof (MPEG_L3_ENC_PRIVATE)) ;
81 	if (!pmpeg)
82 		return SFE_MALLOC_FAILED ;
83 
84 	if (psf->sf.channels < 1 || psf->sf.channels > 2)
85 		return SFE_BAD_OPEN_FORMAT ;
86 
87 	if (! (pmpeg->lamef = lame_init ()))
88 		return SFE_MALLOC_FAILED ;
89 
90 	pmpeg->compression = -1.0 ; /* Unset */
91 
92 	lame_set_in_samplerate (pmpeg->lamef, psf->sf.samplerate) ;
93 	lame_set_num_channels (pmpeg->lamef, psf->sf.channels) ;
94 	if (lame_set_out_samplerate (pmpeg->lamef, psf->sf.samplerate) < 0)
95 		return SFE_MPEG_BAD_SAMPLERATE ;
96 
97 	lame_set_write_id3tag_automatic (pmpeg->lamef, 0) ;
98 
99 	if (!info_tag || psf->is_pipe)
100 	{	/* Can't seek back, so force disable Xing/Lame/Info header. */
101 		lame_set_bWriteVbrTag (pmpeg->lamef, 0) ;
102 		} ;
103 
104 	if (psf->sf.channels == 2)
105 	{	psf->write_short	= mpeg_l3_encode_write_short_stereo ;
106 		psf->write_int		= mpeg_l3_encode_write_int_stereo ;
107 		psf->write_float	= mpeg_l3_encode_write_float_stereo ;
108 		psf->write_double	= mpeg_l3_encode_write_double_stereo ;
109 		}
110 	else
111 	{	psf->write_short	= mpeg_l3_encode_write_short_mono ;
112 		psf->write_int		= mpeg_l3_encode_write_int_mono ;
113 		psf->write_float	= mpeg_l3_encode_write_float_mono ;
114 		psf->write_double	= mpeg_l3_encode_write_double_mono ;
115 		}
116 
117 	psf->sf.seekable	= 0 ;
118 	psf->codec_close	= mpeg_l3_encoder_close ;
119 	psf->byterate		= mpeg_l3_encoder_byterate ;
120 	psf->datalength		= 0 ;
121 
122 	return 0 ;
123 } /* mpeg_l3_encoder_init */
124 
125 int
mpeg_l3_encoder_write_id3tag(SF_PRIVATE * psf)126 mpeg_l3_encoder_write_id3tag (SF_PRIVATE *psf)
127 {	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
128 	unsigned char *id3v2_buffer ;
129 	int i, id3v2_size ;
130 
131 	if (psf->have_written)
132 		return 0 ;
133 
134 	if ((i = mpeg_l3_encoder_construct (psf)))
135 		return i ;
136 
137 	if (psf_fseek (psf, 0, SEEK_SET) != 0)
138 		return SFE_NOT_SEEKABLE ;
139 
140 	/* Safe to call multiple times. */
141 	id3tag_init (pmpeg->lamef) ;
142 
143 	for (i = 0 ; i < SF_MAX_STRINGS ; i++)
144 	{	switch (psf->strings.data [i].type)
145 		{	case SF_STR_TITLE :
146 				id3tag_set_title (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
147 				break ;
148 
149 			case SF_STR_ARTIST :
150 				id3tag_set_artist (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
151 				break ;
152 
153 			case SF_STR_ALBUM :
154 				id3tag_set_album (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
155 				break ;
156 
157 			case SF_STR_DATE :
158 				id3tag_set_year (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
159 				break ;
160 
161 			case SF_STR_COMMENT :
162 				id3tag_set_comment (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
163 				break ;
164 
165 			case SF_STR_GENRE :
166 				id3tag_set_genre (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
167 				break ;
168 
169 			case SF_STR_TRACKNUMBER :
170 				id3tag_set_track (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
171 				break ;
172 
173 			default:
174 				break ;
175 			} ;
176 		} ;
177 
178 	/* The header in this case is the ID3v2 tag header. */
179 	id3v2_size = lame_get_id3v2_tag (pmpeg->lamef, 0, 0) ;
180 	if (id3v2_size > 0)
181 	{	psf_log_printf (psf, "Writing ID3v2 header.\n") ;
182 		if (! (id3v2_buffer = malloc (id3v2_size)))
183 			return SFE_MALLOC_FAILED ;
184 		lame_get_id3v2_tag (pmpeg->lamef, id3v2_buffer, id3v2_size) ;
185 		psf_fwrite (id3v2_buffer, 1, id3v2_size, psf) ;
186 		psf->dataoffset = id3v2_size ;
187 		free (id3v2_buffer) ;
188 		} ;
189 
190 	return 0 ;
191 }
192 
193 int
mpeg_l3_encoder_set_quality(SF_PRIVATE * psf,double compression)194 mpeg_l3_encoder_set_quality (SF_PRIVATE *psf, double compression)
195 {	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
196 	int bitrate_mode ;
197 	int bitrate ;
198 	int ret ;
199 
200 	if (compression < 0.0 || compression > 1.0)
201 		return SF_FALSE ;
202 
203 	/*
204 	** Save the compression setting, as we may have to re-interpret it if
205 	** the bitrate mode changes.
206 	*/
207 	pmpeg->compression = compression ;
208 
209 	bitrate_mode = mpeg_l3_encoder_get_bitrate_mode (psf) ;
210 	if (bitrate_mode == SF_BITRATE_MODE_VARIABLE)
211 	{	ret = lame_set_VBR_quality (pmpeg->lamef, compression * 10.0) ;
212 		}
213 	else
214 	{	/* Choose a bitrate. */
215 		if (psf->sf.samplerate >= 32000)
216 		{	/* MPEG-1.0, bitrates are [32,320] kbps */
217 			bitrate = (320.0 - (compression * (320.0 - 32.0))) ;
218 			}
219 		else if (psf->sf.samplerate >= 16000)
220 		{	/* MPEG-2.0, bitrates are [8,160] */
221 			bitrate = (160.0 - (compression * (160.0 - 8.0))) ;
222 			}
223 		else
224 		{	/* MPEG-2.5, bitrates are [8,64] */
225 			bitrate = (64.0 - (compression * (64.0 - 8.0))) ;
226 			}
227 
228 		if (bitrate_mode == SF_BITRATE_MODE_AVERAGE)
229 			ret = lame_set_VBR_mean_bitrate_kbps (pmpeg->lamef, bitrate) ;
230 		else
231 			ret = lame_set_brate (pmpeg->lamef, bitrate) ;
232 		} ;
233 
234 	if (ret == LAME_OKAY)
235 		return SF_TRUE ;
236 
237 	psf_log_printf (psf, "Failed to set lame encoder quality.\n") ;
238 	return SF_FALSE ;
239 } /* mpeg_l3_encoder_set_quality */
240 
241 int
mpeg_l3_encoder_set_bitrate_mode(SF_PRIVATE * psf,int mode)242 mpeg_l3_encoder_set_bitrate_mode (SF_PRIVATE *psf, int mode)
243 {	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
244 	enum vbr_mode_e vbr_mode ;
245 
246 	if (pmpeg->initialized)
247 	{	psf->error = SFE_CMD_HAS_DATA ;
248 		return SF_FALSE ;
249 		} ;
250 
251 	switch (mode)
252 	{	case SF_BITRATE_MODE_CONSTANT :	vbr_mode = vbr_off ; break ;
253 		case SF_BITRATE_MODE_AVERAGE : vbr_mode = vbr_abr ; break ;
254 		case SF_BITRATE_MODE_VARIABLE : vbr_mode = vbr_default ; break ;
255 		default :
256 			psf->error = SFE_BAD_COMMAND_PARAM ;
257 			return SF_FALSE ;
258 		} ;
259 
260 	if (lame_set_VBR (pmpeg->lamef, vbr_mode) == LAME_OKAY)
261 	{	/* Re-evaluate the compression setting. */
262 		return mpeg_l3_encoder_set_quality (psf, pmpeg->compression) ;
263 		} ;
264 
265 	psf_log_printf (psf, "Failed to set LAME vbr mode to %d.\n", vbr_mode) ;
266 	return SF_FALSE ;
267 } /* mpeg_l3_encoder_set_bitrate_mode */
268 
269 int
mpeg_l3_encoder_get_bitrate_mode(SF_PRIVATE * psf)270 mpeg_l3_encoder_get_bitrate_mode (SF_PRIVATE *psf)
271 {	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
272 	enum vbr_mode_e vbr_mode ;
273 
274 	vbr_mode = lame_get_VBR (pmpeg->lamef) ;
275 
276 	if (vbr_mode == vbr_off)
277 		return SF_BITRATE_MODE_CONSTANT ;
278 	if (vbr_mode == vbr_abr)
279 		return SF_BITRATE_MODE_AVERAGE ;
280 	if (vbr_mode == vbr_default || vbr_mode < vbr_max_indicator)
281 		return SF_BITRATE_MODE_VARIABLE ;
282 
283 	/* Something is wrong. */
284 	psf->error = SFE_INTERNAL ;
285 	return -1 ;
286 } /* mpeg_l3_encoder_get_bitrate_mode */
287 
288 
289 /*-----------------------------------------------------------------------------------------------
290 ** Private functions.
291 */
292 
293 static int
mpeg_l3_encoder_close(SF_PRIVATE * psf)294 mpeg_l3_encoder_close (SF_PRIVATE *psf)
295 {	MPEG_L3_ENC_PRIVATE* pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
296 	int ret, len ;
297 	sf_count_t pos ;
298 	unsigned char *buffer ;
299 
300 	/* Magic number 7200 comes from a comment in lame.h */
301 	len = 7200 ;
302 	if (! (buffer = malloc (len)))
303 		return SFE_MALLOC_FAILED ;
304 	ret = lame_encode_flush (pmpeg->lamef, buffer, len) ;
305 	if (ret > 0)
306 		psf_fwrite (buffer, 1, ret, psf) ;
307 
308 	/*
309 	** Write an IDv1 trailer. The whole tag structure is always 128 bytes, so is
310 	** guaranteed to fit in the buffer allocated above.
311 	*/
312 	ret = lame_get_id3v1_tag (pmpeg->lamef, buffer, len) ;
313 	if (ret > 0)
314 	{	psf_log_printf (psf, "  Writing ID3v1 trailer.\n") ;
315 		psf_fwrite (buffer, 1, ret, psf) ;
316 		} ;
317 
318 	/*
319 	** If possible, seek back and write the LAME/XING/Info headers. This
320 	** contains information about the whole file and a seek table, and can
321 	** only be written after encoding.
322 	**
323 	** If enabled, Lame wrote an empty header at the beginning of the data
324 	** that we now fill in.
325 	*/
326 	ret = lame_get_lametag_frame (pmpeg->lamef, 0, 0) ;
327 	if (ret > 0)
328 	{	if (ret > len)
329 		{	len = ret ;
330 			free (buffer) ;
331 			if (! (buffer = malloc (len)))
332 				return SFE_MALLOC_FAILED ;
333 			} ;
334 		psf_log_printf (psf, "  Writing LAME info header at offset %d, %d bytes.\n",
335 			psf->dataoffset, len) ;
336 		lame_get_lametag_frame (pmpeg->lamef, buffer, len) ;
337 		pos = psf_ftell (psf) ;
338 		if (psf_fseek (psf, psf->dataoffset, SEEK_SET) == psf->dataoffset)
339 		{	psf_fwrite (buffer, 1, ret, psf) ;
340 			psf_fseek (psf, pos, SEEK_SET) ;
341 			} ;
342 		} ;
343 	free (buffer) ;
344 
345 	free (pmpeg->block) ;
346 	pmpeg->block = NULL ;
347 
348 	if (pmpeg->lamef)
349 	{	lame_close (pmpeg->lamef) ;
350 		pmpeg->lamef = NULL ;
351 		} ;
352 
353 	return 0 ;
354 } /* mpeg_l3_encoder_close */
355 
356 static void
mpeg_l3_encoder_log_config(SF_PRIVATE * psf,lame_t lamef)357 mpeg_l3_encoder_log_config (SF_PRIVATE *psf, lame_t lamef)
358 {	const char *version ;
359 	const char *chn_mode ;
360 
361 	switch (lame_get_version (lamef))
362 	{	case 0 : version = "2" ; break ;
363 		case 1 : version = "1" ; break ;
364 		case 2 : version = "2.5" ; break ;
365 		default : version = "unknown!?" ; break ;
366 		} ;
367 	switch (lame_get_mode (lamef))
368 	{	case STEREO : chn_mode = "stereo" ; break ;
369 		case JOINT_STEREO : chn_mode = "joint-stereo" ; break ;
370 		case MONO : chn_mode = "mono" ; break ;
371 		default : chn_mode = "unknown!?" ; break ;
372 		} ;
373 	psf_log_printf (psf, "  MPEG Version      : %s\n", version) ;
374 	psf_log_printf (psf, "  Block samples     : %d\n", lame_get_framesize (lamef)) ;
375 	psf_log_printf (psf, "  Channel mode      : %s\n", chn_mode) ;
376 	psf_log_printf (psf, "  Samplerate        : %d\n", lame_get_out_samplerate (lamef)) ;
377 	psf_log_printf (psf, "  Encoder mode      : ") ;
378 	switch (lame_get_VBR (lamef))
379 	{	case vbr_off :
380 			psf_log_printf (psf, "CBR\n") ;
381 			psf_log_printf (psf, "  Bitrate           : %d kbps\n", lame_get_brate (lamef)) ;
382 			break ;
383 		case vbr_abr :
384 			psf_log_printf (psf, "ABR\n") ;
385 			psf_log_printf (psf, "  Mean Bitrate      : %d kbps\n", lame_get_VBR_mean_bitrate_kbps (lamef)) ;
386 			break ;
387 
388 		case vbr_mt :
389 		case vbr_default :
390 			psf_log_printf (psf, "VBR\n") ;
391 			psf_log_printf (psf, "  Quality           : %d\n", lame_get_VBR_q (lamef)) ;
392 			break ;
393 
394 		default:
395 			psf_log_printf (psf, "Unknown!? (%d)\n", lame_get_VBR (lamef)) ;
396 			break ;
397 		} ;
398 
399 	psf_log_printf (psf, "  Encoder delay     : %d\n", lame_get_encoder_delay (lamef)) ;
400 	psf_log_printf (psf, "  Write INFO header : %d\n", lame_get_bWriteVbrTag (lamef)) ;
401 } /* mpeg_l3_encoder_log_config */
402 
403 static int
mpeg_l3_encoder_construct(SF_PRIVATE * psf)404 mpeg_l3_encoder_construct (SF_PRIVATE *psf)
405 {	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
406 	int frame_samples_per_channel ;
407 
408 	if (pmpeg->initialized == SF_FALSE)
409 	{	if (lame_init_params (pmpeg->lamef) < 0)
410 		{	psf_log_printf (psf, "Failed to initialize lame encoder!\n") ;
411 			return SFE_INTERNAL ;
412 			} ;
413 
414 		psf_log_printf (psf, "Initialized LAME encoder.\n") ;
415 		mpeg_l3_encoder_log_config (psf, pmpeg->lamef) ;
416 
417 		frame_samples_per_channel = lame_get_framesize (pmpeg->lamef) ;
418 
419 		/*
420 		 * Suggested output buffer size in bytes from lame.h comment is
421 		 * 1.25 * samples + 7200
422 		 */
423 		pmpeg->block_len = (frame_samples_per_channel * 4) / 3 + 7200 ;
424 		pmpeg->frame_samples = frame_samples_per_channel * psf->sf.channels ;
425 
426 		pmpeg->block = malloc (pmpeg->block_len) ;
427 		if (!pmpeg->block)
428 			return SFE_MALLOC_FAILED ;
429 
430 		pmpeg->initialized = SF_TRUE ;
431 		} ;
432 
433 	return 0 ;
434 } /* mpeg_l3_encoder_construct */
435 
436 static int
mpeg_l3_encoder_byterate(SF_PRIVATE * psf)437 mpeg_l3_encoder_byterate (SF_PRIVATE *psf)
438 {	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
439 	int bitrate_mode ;
440 	int byterate ;
441 	float calculated_byterate ;
442 
443 	bitrate_mode = mpeg_l3_encoder_get_bitrate_mode (psf) ;
444 	byterate = (lame_get_brate (pmpeg->lamef) + 7) / 8 ;
445 
446 	if (bitrate_mode == SF_BITRATE_MODE_VARIABLE)
447 	{	/*
448 		** For VBR, lame_get_brate returns the minimum bitrate, so calculate the
449 		** average byterate so far.
450 		*/
451 		calculated_byterate = psf_ftell (psf) - psf->dataoffset ;
452 		calculated_byterate /= (float) psf->write_current ;
453 		calculated_byterate *= (float) psf->sf.samplerate ;
454 
455 		return SF_MIN (byterate, (int) calculated_byterate) ;
456 	}
457 
458 	return byterate ;
459 } /* mpeg_l3_encoder_byterate */
460 
461 static sf_count_t
mpeg_l3_encode_write_short_mono(SF_PRIVATE * psf,const short * ptr,sf_count_t len)462 mpeg_l3_encode_write_short_mono (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
463 {	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
464 	sf_count_t total = 0 ;
465 	int nbytes, writecount, writen ;
466 
467 	if ((psf->error = mpeg_l3_encoder_construct (psf)))
468 		return 0 ;
469 
470 	while (len)
471 	{	writecount = SF_MIN (len, (sf_count_t) pmpeg->frame_samples) ;
472 
473 		nbytes = lame_encode_buffer (pmpeg->lamef, ptr + total, NULL, writecount, pmpeg->block, pmpeg->block_len) ;
474 		if (nbytes < 0)
475 		{	psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
476 			break ;
477 			} ;
478 
479 		if (nbytes)
480 		{	writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
481 			if (writen != nbytes)
482 			{	psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
483 				} ;
484 			} ;
485 
486 		total += writecount ;
487 		len -= writecount ;
488 		} ;
489 
490 	return total ;
491 }
492 
493 
494 static sf_count_t
mpeg_l3_encode_write_short_stereo(SF_PRIVATE * psf,const short * ptr,sf_count_t len)495 mpeg_l3_encode_write_short_stereo (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
496 {	BUF_UNION ubuf ;
497 	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
498 	sf_count_t total = 0 ;
499 	int nbytes, writecount, writen ;
500 
501 	if ((psf->error = mpeg_l3_encoder_construct (psf)))
502 		return 0 ;
503 
504 	const sf_count_t max_samples = SF_MIN (ARRAY_LEN (ubuf.sbuf), pmpeg->frame_samples) ;
505 	while (len)
506 	{	writecount = SF_MIN (len, max_samples) ;
507 		/*
508 		 * An oversight, but lame_encode_buffer_interleaved() lacks a const.
509 		 * As such, need another memcpy to not cause a warning.
510 		 */
511 		memcpy (ubuf.sbuf, ptr + total, writecount) ;
512 		nbytes = lame_encode_buffer_interleaved (pmpeg->lamef, ubuf.sbuf, writecount / 2, pmpeg->block, pmpeg->block_len) ;
513 		if (nbytes < 0)
514 		{	psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
515 			break ;
516 			} ;
517 
518 		if (nbytes)
519 		{	writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
520 			if (writen != nbytes)
521 			{	psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
522 				} ;
523 			} ;
524 
525 		total += writecount ;
526 		len -= writecount ;
527 		} ;
528 
529 	return total ;
530 }
531 
532 
533 static sf_count_t
mpeg_l3_encode_write_int_mono(SF_PRIVATE * psf,const int * ptr,sf_count_t len)534 mpeg_l3_encode_write_int_mono (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
535 {	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
536 	sf_count_t total = 0 ;
537 	int nbytes, writecount, writen ;
538 
539 	if ((psf->error = mpeg_l3_encoder_construct (psf)))
540 		return 0 ;
541 
542 	while (len)
543 	{	writecount = SF_MIN (len, (sf_count_t) pmpeg->frame_samples) ;
544 
545 		nbytes = lame_encode_buffer_int (pmpeg->lamef, ptr + total, NULL, writecount, pmpeg->block, pmpeg->block_len) ;
546 		if (nbytes < 0)
547 		{	psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
548 			break ;
549 			} ;
550 
551 		if (nbytes)
552 		{	writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
553 			if (writen != nbytes)
554 			{	psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
555 				} ;
556 			} ;
557 
558 		total += writecount ;
559 		len -= writecount ;
560 		} ;
561 
562 	return total ;
563 }
564 
565 
566 static sf_count_t
mpeg_l3_encode_write_int_stereo(SF_PRIVATE * psf,const int * ptr,sf_count_t len)567 mpeg_l3_encode_write_int_stereo (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
568 {	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
569 	sf_count_t total = 0 ;
570 	int nbytes, writecount, writen ;
571 
572 	if ((psf->error = mpeg_l3_encoder_construct (psf)))
573 		return 0 ;
574 
575 	while (len)
576 	{	writecount = SF_MIN (len, (sf_count_t) pmpeg->frame_samples) ;
577 
578 		nbytes = lame_encode_buffer_interleaved_int (pmpeg->lamef, ptr + total, writecount / 2, pmpeg->block, pmpeg->block_len) ;
579 		if (nbytes < 0)
580 		{	psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
581 			break ;
582 			} ;
583 
584 		if (nbytes)
585 		{	writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
586 			if (writen != nbytes)
587 			{	psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
588 				} ;
589 			} ;
590 
591 		total += writecount ;
592 		len -= writecount ;
593 		} ;
594 
595 	return total ;
596 }
597 
598 
599 static sf_count_t
mpeg_l3_encode_write_float_mono(SF_PRIVATE * psf,const float * ptr,sf_count_t len)600 mpeg_l3_encode_write_float_mono (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
601 {	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
602 	sf_count_t total = 0 ;
603 	int nbytes, writecount, writen ;
604 
605 	if ((psf->error = mpeg_l3_encoder_construct (psf)))
606 		return 0 ;
607 
608 	while (len)
609 	{	writecount = SF_MIN (len, (sf_count_t) pmpeg->frame_samples) ;
610 
611 		if (psf->norm_float)
612 			nbytes = lame_encode_buffer_ieee_float (pmpeg->lamef, ptr + total, NULL, writecount, pmpeg->block, pmpeg->block_len) ;
613 		else
614 			nbytes = lame_encode_buffer_float (pmpeg->lamef, ptr + total, NULL, writecount, pmpeg->block, pmpeg->block_len) ;
615 		if (nbytes < 0)
616 		{	psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
617 			break ;
618 			} ;
619 
620 		if (nbytes)
621 		{	writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
622 			if (writen != nbytes)
623 			{	psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
624 				} ;
625 			} ;
626 
627 		total += writecount ;
628 		len -= writecount ;
629 		} ;
630 
631 	return total ;
632 }
633 
634 
635 static inline void
normalize_float(float * dest,const float * src,sf_count_t count,float norm_fact)636 normalize_float (float *dest, const float *src, sf_count_t count, float norm_fact)
637 {	while (--count >= 0)
638 	{	dest [count] = src [count] * norm_fact ;
639 		} ;
640 }
641 
642 
643 static sf_count_t
mpeg_l3_encode_write_float_stereo(SF_PRIVATE * psf,const float * ptr,sf_count_t len)644 mpeg_l3_encode_write_float_stereo (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
645 {	BUF_UNION ubuf ;
646 	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
647 	sf_count_t total = 0 ;
648 	int nbytes, writecount, writen ;
649 
650 	if ((psf->error = mpeg_l3_encoder_construct (psf)))
651 		return 0 ;
652 
653 	const sf_count_t max_samples = SF_MIN (ARRAY_LEN (ubuf.fbuf), pmpeg->frame_samples) ;
654 	while (len)
655 	{	writecount = SF_MIN (len, max_samples) ;
656 
657 		if (psf->norm_float)
658 			nbytes = lame_encode_buffer_interleaved_ieee_float (pmpeg->lamef, ptr + total, writecount / 2, pmpeg->block, pmpeg->block_len) ;
659 		else
660 		{	/* Lame lacks a non-normalized interleaved float write. Bummer. */
661 			normalize_float (ubuf.fbuf, ptr + total, writecount, 1.0 / (float) 0x8000) ;
662 			nbytes = lame_encode_buffer_interleaved_ieee_float (pmpeg->lamef, ubuf.fbuf, writecount / 2, pmpeg->block, pmpeg->block_len) ;
663 			}
664 
665 		if (nbytes < 0)
666 		{	psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
667 			break ;
668 			} ;
669 
670 		if (nbytes)
671 		{	writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
672 			if (writen != nbytes)
673 			{	psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
674 				} ;
675 			} ;
676 
677 		total += writecount ;
678 		len -= writecount ;
679 		} ;
680 
681 	return total ;
682 }
683 
684 
685 static inline void
normalize_double(double * dest,const double * src,sf_count_t count,double norm_fact)686 normalize_double (double *dest, const double *src, sf_count_t count, double norm_fact)
687 {	while (--count >= 0)
688 	{	dest [count] = src [count] * norm_fact ;
689 		} ;
690 }
691 
692 
693 static sf_count_t
mpeg_l3_encode_write_double_mono(SF_PRIVATE * psf,const double * ptr,sf_count_t len)694 mpeg_l3_encode_write_double_mono (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
695 {	BUF_UNION ubuf ;
696 	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
697 	sf_count_t total = 0 ;
698 	int nbytes, writecount, writen ;
699 
700 	if ((psf->error = mpeg_l3_encoder_construct (psf)))
701 		return 0 ;
702 
703 	const sf_count_t max_samples = SF_MIN (ARRAY_LEN (ubuf.dbuf), pmpeg->frame_samples) ;
704 	while (len)
705 	{	writecount = SF_MIN (len, max_samples) ;
706 
707 		if (psf->norm_double)
708 			nbytes = lame_encode_buffer_ieee_double (pmpeg->lamef, ptr + total, NULL, writecount, pmpeg->block, pmpeg->block_len) ;
709 		else
710 		{	/* Lame lacks non-normalized double writing */
711 			normalize_double (ubuf.dbuf, ptr + total, writecount, 1.0 / (double) 0x8000) ;
712 			nbytes = lame_encode_buffer_ieee_double (pmpeg->lamef, ubuf.dbuf, NULL, writecount, pmpeg->block, pmpeg->block_len) ;
713 			}
714 
715 		if (nbytes < 0)
716 		{	psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
717 			break ;
718 			} ;
719 
720 		if (nbytes)
721 		{	writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
722 			if (writen != nbytes)
723 			{	psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
724 				} ;
725 			} ;
726 
727 		total += writecount ;
728 		len -= writecount ;
729 		} ;
730 
731 	return total ;
732 }
733 
734 
735 static sf_count_t
mpeg_l3_encode_write_double_stereo(SF_PRIVATE * psf,const double * ptr,sf_count_t len)736 mpeg_l3_encode_write_double_stereo (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
737 {	BUF_UNION ubuf ;
738 	MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
739 	sf_count_t total = 0 ;
740 	int nbytes, writecount, writen ;
741 
742 	if ((psf->error = mpeg_l3_encoder_construct (psf)))
743 		return 0 ;
744 
745 	const sf_count_t max_samples = SF_MIN (ARRAY_LEN (ubuf.dbuf), pmpeg->frame_samples) ;
746 	while (len)
747 	{	writecount = SF_MIN (len, max_samples) ;
748 
749 		if (psf->norm_double)
750 			nbytes = lame_encode_buffer_interleaved_ieee_double (pmpeg->lamef, ptr + total, writecount / 2, pmpeg->block, pmpeg->block_len) ;
751 		else
752 		{	/* Lame lacks interleaved non-normalized double writing */
753 			normalize_double (ubuf.dbuf, ptr + total, writecount, 1.0 / (double) 0x8000) ;
754 			nbytes = lame_encode_buffer_interleaved_ieee_double (pmpeg->lamef, ubuf.dbuf, writecount / 2, pmpeg->block, pmpeg->block_len) ;
755 			}
756 
757 		if (nbytes < 0)
758 		{	psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
759 			break ;
760 			} ;
761 
762 		if (nbytes)
763 		{	writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
764 			if (writen != nbytes)
765 			{	psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
766 				} ;
767 			} ;
768 
769 		total += writecount ;
770 		len -= writecount ;
771 		} ;
772 
773 	return total ;
774 }
775 
776 #else /* HAVE_MPEG */
777 
778 int
mpeg_l3_encoder_init(SF_PRIVATE * psf,int UNUSED (vbr))779 mpeg_l3_encoder_init (SF_PRIVATE *psf, int UNUSED (vbr))
780 {	psf_log_printf (psf, "This version of libsndfile was compiled without MPEG Layer 3 encoding support.\n") ;
781 	return SFE_UNIMPLEMENTED ;
782 } /* mpeg_l3_encoder_init */
783 
784 #endif
785