2 * Copyright (C) 2003-2010 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
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 General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "config.h" /* must be first for large file support */
21 #include "decoder_api.h"
22 #include "audio_check.h"
29 #define G_LOG_DOMAIN "mpg123"
32 mpd_mpg123_init(G_GNUC_UNUSED
const struct config_param
*param
)
40 mpd_mpg123_finish(void)
46 * Opens a file with an existing #mpg123_handle.
48 * @param handle a handle which was created before; on error, this
49 * function will not free it
50 * @param audio_format this parameter is filled after successful
52 * @return true on success
55 mpd_mpg123_open(mpg123_handle
*handle
, const char *path_fs
,
56 struct audio_format
*audio_format
)
58 GError
*gerror
= NULL
;
61 int channels
, encoding
;
64 /* mpg123_open() wants a writable string :-( */
65 path_dup
= g_strdup(path_fs
);
67 error
= mpg123_open(handle
, path_dup
);
69 if (error
!= MPG123_OK
) {
70 g_warning("libmpg123 failed to open %s: %s",
71 path_fs
, mpg123_plain_strerror(error
));
75 /* obtain the audio format */
77 error
= mpg123_getformat(handle
, &rate
, &channels
, &encoding
);
78 if (error
!= MPG123_OK
) {
79 g_warning("mpg123_getformat() failed: %s",
80 mpg123_plain_strerror(error
));
84 if (encoding
!= MPG123_ENC_SIGNED_16
) {
85 /* other formats not yet implemented */
86 g_warning("expected MPG123_ENC_SIGNED_16, got %d", encoding
);
90 if (!audio_format_init_checked(audio_format
, rate
, SAMPLE_FORMAT_S16
,
92 g_warning("%s", gerror
->message
);
101 mpd_mpg123_file_decode(struct decoder
*decoder
, const char *path_fs
)
103 struct audio_format audio_format
;
104 mpg123_handle
*handle
;
107 enum decoder_command cmd
;
111 handle
= mpg123_new(NULL
, &error
);
112 if (handle
== NULL
) {
113 g_warning("mpg123_new() failed: %s",
114 mpg123_plain_strerror(error
));
118 if (!mpd_mpg123_open(handle
, path_fs
, &audio_format
)) {
119 mpg123_delete(handle
);
123 num_samples
= mpg123_length(handle
);
125 /* tell MPD core we're ready */
127 decoder_initialized(decoder
, &audio_format
, false,
129 (float)audio_format
.sample_rate
);
131 /* the decoder main loop */
134 unsigned char buffer
[8192];
139 error
= mpg123_read(handle
, buffer
, sizeof(buffer
), &nbytes
);
140 if (error
!= MPG123_OK
) {
141 if (error
!= MPG123_DONE
)
142 g_warning("mpg123_read() failed: %s",
143 mpg123_plain_strerror(error
));
149 cmd
= decoder_data(decoder
, NULL
, buffer
, nbytes
,
152 /* seeking not yet implemented */
153 } while (cmd
== DECODE_COMMAND_NONE
);
157 mpg123_delete(handle
);
161 mpd_mpg123_tag_dup(const char *path_fs
)
163 struct audio_format audio_format
;
164 mpg123_handle
*handle
;
169 handle
= mpg123_new(NULL
, &error
);
170 if (handle
== NULL
) {
171 g_warning("mpg123_new() failed: %s",
172 mpg123_plain_strerror(error
));
176 if (!mpd_mpg123_open(handle
, path_fs
, &audio_format
)) {
177 mpg123_delete(handle
);
181 num_samples
= mpg123_length(handle
);
182 if (num_samples
<= 0) {
183 mpg123_delete(handle
);
189 tag
->time
= num_samples
/ audio_format
.sample_rate
;
191 /* ID3 tag support not yet implemented */
193 mpg123_delete(handle
);
197 static const char *const mpg123_suffixes
[] = {
202 const struct decoder_plugin mpg123_decoder_plugin
= {
204 .init
= mpd_mpg123_init
,
205 .finish
= mpd_mpg123_finish
,
206 .file_decode
= mpd_mpg123_file_decode
,
207 /* streaming not yet implemented */
208 .tag_dup
= mpd_mpg123_tag_dup
,
209 .suffixes
= mpg123_suffixes
,