1/* 2** Copyright (C) 2019 Erik de Castro Lopo <erikd@mega-nerd.com> 3** Copyright (C) 2021 Arthur Taylor <art@ified.ca> 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 22#include "sndfile.h" 23#include "common.h" 24 25#if HAVE_MPEG 26 27#include "mpeg.h" 28 29static int mpeg_write_header (SF_PRIVATE *psf, int calc_length) ; 30static int mpeg_command (SF_PRIVATE *psf, int command, void *data, int datasize) ; 31 32/*------------------------------------------------------------------------------ 33 * Private functions 34 */ 35 36static int 37mpeg_write_header (SF_PRIVATE *psf, int UNUSED (calc_length)) 38{ 39 if (psf->have_written) 40 return 0 ; 41 42 return mpeg_l3_encoder_write_id3tag (psf) ; 43} 44 45static int 46mpeg_command (SF_PRIVATE *psf, int command, void *data, int datasize) 47{ int bitrate_mode ; 48 49 switch (command) 50 { case SFC_SET_COMPRESSION_LEVEL : 51 if (data == NULL || datasize != sizeof (double)) 52 { psf->error = SFE_BAD_COMMAND_PARAM ; 53 return SF_FALSE ; 54 } ; 55 if (psf->file.mode != SFM_WRITE) 56 { psf->error = SFE_NOT_WRITEMODE ; 57 return SF_FALSE ; 58 } ; 59 return mpeg_l3_encoder_set_quality (psf, *(double *) data) ; 60 61 case SFC_SET_BITRATE_MODE : 62 if (psf->file.mode != SFM_WRITE) 63 { psf->error = SFE_NOT_WRITEMODE ; 64 return SF_FALSE ; 65 } ; 66 if (data == NULL || datasize != sizeof (int)) 67 { psf->error = SFE_BAD_COMMAND_PARAM ; 68 return SF_FALSE ; 69 } ; 70 bitrate_mode = *(int *) data ; 71 return mpeg_l3_encoder_set_bitrate_mode (psf, bitrate_mode) ; 72 73 case SFC_GET_BITRATE_MODE : 74 if (psf->file.mode == SFM_READ) 75 return mpeg_decoder_get_bitrate_mode (psf) ; 76 else 77 return mpeg_l3_encoder_get_bitrate_mode (psf) ; 78 79 default : 80 return SF_FALSE ; 81 } ; 82 83 return SF_FALSE ; 84} /* mpeg_command */ 85 86/*------------------------------------------------------------------------------ 87 * Public functions 88 */ 89 90int 91mpeg_init (SF_PRIVATE *psf, int bitrate_mode, int write_metadata) 92{ int error ; 93 94 if (psf->file.mode == SFM_RDWR) 95 return SFE_BAD_MODE_RW ; 96 97 if (psf->file.mode == SFM_WRITE) 98 { switch (SF_CODEC (psf->sf.format)) 99 { case SF_FORMAT_MPEG_LAYER_III : 100 if ((error = mpeg_l3_encoder_init (psf, write_metadata))) 101 return error ; 102 mpeg_l3_encoder_set_bitrate_mode (psf, bitrate_mode) ; 103 if (write_metadata) 104 { /* ID3 support */ 105 psf->strings.flags = SF_STR_ALLOW_START ; 106 psf->write_header = mpeg_write_header ; 107 } ; 108 break ; 109 110 case SF_FORMAT_MPEG_LAYER_I : 111 case SF_FORMAT_MPEG_LAYER_II : 112 psf_log_printf (psf, "MPEG Layer I and II encoding is not yet supported.\n") ; 113 return SFE_UNIMPLEMENTED ; 114 115 default: 116 psf_log_printf (psf, "%s: bad psf->sf.format 0x%x.\n", __func__, psf->sf.format) ; 117 return SFE_INTERNAL ; 118 } ; 119 } ; 120 121 if (psf->file.mode == SFM_READ) 122 { if ((error = mpeg_decoder_init (psf))) 123 return error ; 124 } ; 125 126 return 0 ; 127} /* mpeg_init */ 128 129int 130mpeg_open (SF_PRIVATE *psf) 131{ int error ; 132 133 /* Choose variable bitrate mode by default for standalone files.*/ 134 if ((error = mpeg_init (psf, SF_BITRATE_MODE_VARIABLE, SF_TRUE))) 135 return error ; 136 137 psf->dataoffset = 0 ; 138 psf->command = mpeg_command ; 139 140 if (psf->filelength != SF_COUNT_MAX) 141 psf->datalength = psf->filelength - psf->dataoffset ; 142 else 143 psf->datalength = SF_COUNT_MAX ; 144 145 146 return 0 ; 147} /* mpeg_open */ 148 149#else /* HAVE_MPEG */ 150 151int 152mpeg_init (SF_PRIVATE *psf, int UNUSED (bitrate_mode) , int UNUSED (write_metadata)) 153{ 154 psf_log_printf (psf, "This version of libsndfile was compiled without MPEG support.\n") ; 155 return SFE_UNIMPLEMENTED ; 156} /* mpeg_init */ 157 158int 159mpeg_open (SF_PRIVATE *psf) 160{ 161 psf_log_printf (psf, "This version of libsndfile was compiled without MP3 support.\n") ; 162 return SFE_UNIMPLEMENTED ; 163} /* mpeg_open */ 164 165#endif 166