1b815c7f3Sopenharmony_ci/*
2b815c7f3Sopenharmony_ci** Copyright (C) 2019 Erik de Castro Lopo <erikd@mega-nerd.com>
3b815c7f3Sopenharmony_ci** Copyright (C) 2021 Arthur Taylor <art@ified.ca>
4b815c7f3Sopenharmony_ci**
5b815c7f3Sopenharmony_ci** This program is free software ; you can redistribute it and/or modify
6b815c7f3Sopenharmony_ci** it under the terms of the GNU Lesser General Public License as published by
7b815c7f3Sopenharmony_ci** the Free Software Foundation ; either version 2.1 of the License, or
8b815c7f3Sopenharmony_ci** (at your option) any later version.
9b815c7f3Sopenharmony_ci**
10b815c7f3Sopenharmony_ci** This program is distributed in the hope that it will be useful,
11b815c7f3Sopenharmony_ci** but WITHOUT ANY WARRANTY ; without even the implied warranty of
12b815c7f3Sopenharmony_ci** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13b815c7f3Sopenharmony_ci** GNU Lesser General Public License for more details.
14b815c7f3Sopenharmony_ci**
15b815c7f3Sopenharmony_ci** You should have received a copy of the GNU Lesser General Public License
16b815c7f3Sopenharmony_ci** along with this program ; if not, write to the Free Software
17b815c7f3Sopenharmony_ci** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18b815c7f3Sopenharmony_ci*/
19b815c7f3Sopenharmony_ci
20b815c7f3Sopenharmony_ci#include	"sfconfig.h"
21b815c7f3Sopenharmony_ci
22b815c7f3Sopenharmony_ci#include	"sndfile.h"
23b815c7f3Sopenharmony_ci#include	"common.h"
24b815c7f3Sopenharmony_ci
25b815c7f3Sopenharmony_ci#if HAVE_MPEG
26b815c7f3Sopenharmony_ci
27b815c7f3Sopenharmony_ci#include "mpeg.h"
28b815c7f3Sopenharmony_ci
29b815c7f3Sopenharmony_cistatic int	mpeg_write_header (SF_PRIVATE *psf, int calc_length) ;
30b815c7f3Sopenharmony_cistatic int	mpeg_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
31b815c7f3Sopenharmony_ci
32b815c7f3Sopenharmony_ci/*------------------------------------------------------------------------------
33b815c7f3Sopenharmony_ci * Private functions
34b815c7f3Sopenharmony_ci */
35b815c7f3Sopenharmony_ci
36b815c7f3Sopenharmony_cistatic int
37b815c7f3Sopenharmony_cimpeg_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
38b815c7f3Sopenharmony_ci{
39b815c7f3Sopenharmony_ci	if (psf->have_written)
40b815c7f3Sopenharmony_ci		return 0 ;
41b815c7f3Sopenharmony_ci
42b815c7f3Sopenharmony_ci	return mpeg_l3_encoder_write_id3tag (psf) ;
43b815c7f3Sopenharmony_ci}
44b815c7f3Sopenharmony_ci
45b815c7f3Sopenharmony_cistatic int
46b815c7f3Sopenharmony_cimpeg_command (SF_PRIVATE *psf, int command, void *data, int datasize)
47b815c7f3Sopenharmony_ci{	int bitrate_mode ;
48b815c7f3Sopenharmony_ci
49b815c7f3Sopenharmony_ci	switch (command)
50b815c7f3Sopenharmony_ci	{	case SFC_SET_COMPRESSION_LEVEL :
51b815c7f3Sopenharmony_ci			if (data == NULL || datasize != sizeof (double))
52b815c7f3Sopenharmony_ci			{	psf->error = SFE_BAD_COMMAND_PARAM ;
53b815c7f3Sopenharmony_ci				return SF_FALSE ;
54b815c7f3Sopenharmony_ci				} ;
55b815c7f3Sopenharmony_ci			if (psf->file.mode != SFM_WRITE)
56b815c7f3Sopenharmony_ci			{	psf->error = SFE_NOT_WRITEMODE ;
57b815c7f3Sopenharmony_ci				return SF_FALSE ;
58b815c7f3Sopenharmony_ci				} ;
59b815c7f3Sopenharmony_ci			return mpeg_l3_encoder_set_quality (psf, *(double *) data) ;
60b815c7f3Sopenharmony_ci
61b815c7f3Sopenharmony_ci		case SFC_SET_BITRATE_MODE :
62b815c7f3Sopenharmony_ci			if (psf->file.mode != SFM_WRITE)
63b815c7f3Sopenharmony_ci			{	psf->error = SFE_NOT_WRITEMODE ;
64b815c7f3Sopenharmony_ci				return SF_FALSE ;
65b815c7f3Sopenharmony_ci				} ;
66b815c7f3Sopenharmony_ci			if (data == NULL || datasize != sizeof (int))
67b815c7f3Sopenharmony_ci			{	psf->error = SFE_BAD_COMMAND_PARAM ;
68b815c7f3Sopenharmony_ci				return SF_FALSE ;
69b815c7f3Sopenharmony_ci				} ;
70b815c7f3Sopenharmony_ci			bitrate_mode = *(int *) data ;
71b815c7f3Sopenharmony_ci			return mpeg_l3_encoder_set_bitrate_mode (psf, bitrate_mode) ;
72b815c7f3Sopenharmony_ci
73b815c7f3Sopenharmony_ci		case SFC_GET_BITRATE_MODE :
74b815c7f3Sopenharmony_ci			if (psf->file.mode == SFM_READ)
75b815c7f3Sopenharmony_ci				return mpeg_decoder_get_bitrate_mode (psf) ;
76b815c7f3Sopenharmony_ci			else
77b815c7f3Sopenharmony_ci				return mpeg_l3_encoder_get_bitrate_mode (psf) ;
78b815c7f3Sopenharmony_ci
79b815c7f3Sopenharmony_ci		default :
80b815c7f3Sopenharmony_ci			return SF_FALSE ;
81b815c7f3Sopenharmony_ci		} ;
82b815c7f3Sopenharmony_ci
83b815c7f3Sopenharmony_ci	return SF_FALSE ;
84b815c7f3Sopenharmony_ci} /* mpeg_command */
85b815c7f3Sopenharmony_ci
86b815c7f3Sopenharmony_ci/*------------------------------------------------------------------------------
87b815c7f3Sopenharmony_ci * Public functions
88b815c7f3Sopenharmony_ci */
89b815c7f3Sopenharmony_ci
90b815c7f3Sopenharmony_ciint
91b815c7f3Sopenharmony_cimpeg_init (SF_PRIVATE *psf, int bitrate_mode, int write_metadata)
92b815c7f3Sopenharmony_ci{	int error ;
93b815c7f3Sopenharmony_ci
94b815c7f3Sopenharmony_ci	if (psf->file.mode == SFM_RDWR)
95b815c7f3Sopenharmony_ci		return SFE_BAD_MODE_RW ;
96b815c7f3Sopenharmony_ci
97b815c7f3Sopenharmony_ci	if (psf->file.mode == SFM_WRITE)
98b815c7f3Sopenharmony_ci	{	switch (SF_CODEC (psf->sf.format))
99b815c7f3Sopenharmony_ci		{	case SF_FORMAT_MPEG_LAYER_III :
100b815c7f3Sopenharmony_ci				if ((error = mpeg_l3_encoder_init (psf, write_metadata)))
101b815c7f3Sopenharmony_ci					return error ;
102b815c7f3Sopenharmony_ci				mpeg_l3_encoder_set_bitrate_mode (psf, bitrate_mode) ;
103b815c7f3Sopenharmony_ci				if (write_metadata)
104b815c7f3Sopenharmony_ci				{	/* ID3 support */
105b815c7f3Sopenharmony_ci					psf->strings.flags = SF_STR_ALLOW_START ;
106b815c7f3Sopenharmony_ci					psf->write_header = mpeg_write_header ;
107b815c7f3Sopenharmony_ci					} ;
108b815c7f3Sopenharmony_ci				break ;
109b815c7f3Sopenharmony_ci
110b815c7f3Sopenharmony_ci			case SF_FORMAT_MPEG_LAYER_I :
111b815c7f3Sopenharmony_ci			case SF_FORMAT_MPEG_LAYER_II :
112b815c7f3Sopenharmony_ci				psf_log_printf (psf, "MPEG Layer I and II encoding is not yet supported.\n") ;
113b815c7f3Sopenharmony_ci				return SFE_UNIMPLEMENTED ;
114b815c7f3Sopenharmony_ci
115b815c7f3Sopenharmony_ci			default:
116b815c7f3Sopenharmony_ci				psf_log_printf (psf, "%s: bad psf->sf.format 0x%x.\n", __func__, psf->sf.format) ;
117b815c7f3Sopenharmony_ci				return SFE_INTERNAL ;
118b815c7f3Sopenharmony_ci			} ;
119b815c7f3Sopenharmony_ci		} ;
120b815c7f3Sopenharmony_ci
121b815c7f3Sopenharmony_ci	if (psf->file.mode == SFM_READ)
122b815c7f3Sopenharmony_ci	{	if ((error = mpeg_decoder_init (psf)))
123b815c7f3Sopenharmony_ci			return error ;
124b815c7f3Sopenharmony_ci		} ;
125b815c7f3Sopenharmony_ci
126b815c7f3Sopenharmony_ci	return 0 ;
127b815c7f3Sopenharmony_ci} /* mpeg_init */
128b815c7f3Sopenharmony_ci
129b815c7f3Sopenharmony_ciint
130b815c7f3Sopenharmony_cimpeg_open (SF_PRIVATE *psf)
131b815c7f3Sopenharmony_ci{	int error ;
132b815c7f3Sopenharmony_ci
133b815c7f3Sopenharmony_ci	/* Choose variable bitrate mode by default for standalone files.*/
134b815c7f3Sopenharmony_ci	if ((error = mpeg_init (psf, SF_BITRATE_MODE_VARIABLE, SF_TRUE)))
135b815c7f3Sopenharmony_ci		return error ;
136b815c7f3Sopenharmony_ci
137b815c7f3Sopenharmony_ci	psf->dataoffset = 0 ;
138b815c7f3Sopenharmony_ci	psf->command = mpeg_command ;
139b815c7f3Sopenharmony_ci
140b815c7f3Sopenharmony_ci	if (psf->filelength != SF_COUNT_MAX)
141b815c7f3Sopenharmony_ci		psf->datalength = psf->filelength - psf->dataoffset ;
142b815c7f3Sopenharmony_ci	else
143b815c7f3Sopenharmony_ci		psf->datalength = SF_COUNT_MAX ;
144b815c7f3Sopenharmony_ci
145b815c7f3Sopenharmony_ci
146b815c7f3Sopenharmony_ci	return 0 ;
147b815c7f3Sopenharmony_ci} /* mpeg_open */
148b815c7f3Sopenharmony_ci
149b815c7f3Sopenharmony_ci#else /* HAVE_MPEG */
150b815c7f3Sopenharmony_ci
151b815c7f3Sopenharmony_ciint
152b815c7f3Sopenharmony_cimpeg_init (SF_PRIVATE *psf, int UNUSED (bitrate_mode) , int UNUSED (write_metadata))
153b815c7f3Sopenharmony_ci{
154b815c7f3Sopenharmony_ci	psf_log_printf (psf, "This version of libsndfile was compiled without MPEG support.\n") ;
155b815c7f3Sopenharmony_ci	return SFE_UNIMPLEMENTED ;
156b815c7f3Sopenharmony_ci} /* mpeg_init */
157b815c7f3Sopenharmony_ci
158b815c7f3Sopenharmony_ciint
159b815c7f3Sopenharmony_cimpeg_open (SF_PRIVATE *psf)
160b815c7f3Sopenharmony_ci{
161b815c7f3Sopenharmony_ci	psf_log_printf (psf, "This version of libsndfile was compiled without MP3 support.\n") ;
162b815c7f3Sopenharmony_ci	return SFE_UNIMPLEMENTED ;
163b815c7f3Sopenharmony_ci} /* mpeg_open */
164b815c7f3Sopenharmony_ci
165b815c7f3Sopenharmony_ci#endif
166