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