2 Copyright (C) 2011-2013 Robin Gareus <robin@gareus.org>
3 Copyright (C) 2014-2023 Filipe Coelho <falktx@falktx.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser Public License as published by
7 the Free Software Foundation; either version 2.1, or (at your option)
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 Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 #include "ad_plugin.h"
28 #define DR_MP3_FLOAT_OUTPUT
29 #define DR_MP3_IMPLEMENTATION
30 #define DRMP3_DATA_CHUNK_SIZE DRMP3_MIN_DATA_CHUNK_SIZE*40
33 /* internal abstraction */
35 #define DR_MP3_MAX_SEEK_POINTS 500
38 #define strcasecmp stricmp
43 drmp3_seek_point seekPoints
[DR_MP3_MAX_SEEK_POINTS
];
44 } drmp3_audio_decoder
;
46 static int ad_info_dr_mp3(void *sf
, struct adinfo
*nfo
) {
47 drmp3_audio_decoder
*priv
= (drmp3_audio_decoder
*) sf
;
50 nfo
->channels
= priv
->mp3
.channels
;
51 nfo
->frames
= drmp3_get_pcm_frame_count(&priv
->mp3
);
52 nfo
->sample_rate
= priv
->mp3
.sampleRate
;
53 nfo
->length
= nfo
->sample_rate
? (nfo
->frames
* 1000) / nfo
->sample_rate
: 0;
55 nfo
->bit_rate
= priv
->mp3
.frameInfo
.bitrate_kbps
* 1000;
56 nfo
->meta_data
= NULL
;
62 static void *ad_open_dr_mp3(const char *filename
, struct adinfo
*nfo
) {
63 drmp3_audio_decoder
*priv
= (drmp3_audio_decoder
*)calloc (1, sizeof(drmp3_audio_decoder
));
64 drmp3_bool32 res
= drmp3_init_file(&priv
->mp3
, filename
, NULL
);
65 if (res
== DRMP3_FALSE
) {
66 dbg(0, "unable to open file '%s'.", filename
);
70 drmp3_uint32 seekPointCount
= DR_MP3_MAX_SEEK_POINTS
;
71 drmp3_calculate_seek_points (&priv
->mp3
, &seekPointCount
, priv
->seekPoints
);
72 drmp3_bind_seek_table (&priv
->mp3
, seekPointCount
, priv
->seekPoints
);
73 ad_info_dr_mp3 (priv
, nfo
);
77 static int ad_close_dr_mp3(void *sf
) {
78 drmp3_audio_decoder
*priv
= (drmp3_audio_decoder
*) sf
;
81 dbg (0, "fatal: bad file close.\n");
84 drmp3_uninit (&priv
->mp3
);
89 static int64_t ad_seek_dr_mp3(void *sf
, int64_t pos
)
91 drmp3_audio_decoder
*priv
= (drmp3_audio_decoder
*) sf
;
93 return drmp3_seek_to_pcm_frame (&priv
->mp3
, pos
);
96 static ssize_t
ad_read_dr_mp3(void *sf
, float* d
, size_t len
)
98 drmp3_audio_decoder
*priv
= (drmp3_audio_decoder
*) sf
;
100 return drmp3_read_pcm_frames_f32 (&priv
->mp3
, len
/ priv
->mp3
.channels
, d
) * priv
->mp3
.channels
;
103 static int ad_get_bitrate_dr_mp3(void *sf
) {
104 drmp3_audio_decoder
*priv
= (drmp3_audio_decoder
*) sf
;
105 if (!priv
) return -1;
106 return priv
->mp3
.frameInfo
.bitrate_kbps
* 1000;
109 static int ad_eval_dr_mp3(const char *f
)
111 char *ext
= strrchr(f
, '.');
112 if (strstr (f
, "://")) return 0;
114 if (!strcasecmp(ext
, ".mp3")) return 100;
118 static const ad_plugin ad_dr_mp3
= {
126 &ad_get_bitrate_dr_mp3
139 const ad_plugin
* adp_get_dr_mp3() {