• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
29 static int	mpeg_write_header (SF_PRIVATE *psf, int calc_length) ;
30 static int	mpeg_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
31 
32 /*------------------------------------------------------------------------------
33  * Private functions
34  */
35 
36 static int
mpeg_write_header(SF_PRIVATE * psf,int UNUSED (calc_length))37 mpeg_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 
45 static int
mpeg_command(SF_PRIVATE * psf,int command,void * data,int datasize)46 mpeg_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 
90 int
mpeg_init(SF_PRIVATE * psf,int bitrate_mode,int write_metadata)91 mpeg_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 
129 int
mpeg_open(SF_PRIVATE * psf)130 mpeg_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 
151 int
mpeg_init(SF_PRIVATE * psf,int UNUSED (bitrate_mode),int UNUSED (write_metadata))152 mpeg_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 
158 int
mpeg_open(SF_PRIVATE * psf)159 mpeg_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