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
27 #include "ad_plugin.h"
29 int ad_debug_level
= 0;
31 #define UNUSED(x) (void)(x)
33 int ad_eval_null(const char *f
) { UNUSED(f
); return -1; }
34 void * ad_open_null(const char *f
, struct adinfo
*n
) { UNUSED(f
); UNUSED(n
); return NULL
; }
35 int ad_close_null(void *x
) { UNUSED(x
); return -1; }
36 int ad_info_null(void *x
, struct adinfo
*n
) { UNUSED(x
); UNUSED(n
); return -1; }
37 int64_t ad_seek_null(void *x
, int64_t p
) { UNUSED(x
); UNUSED(p
); return -1; }
38 ssize_t
ad_read_null(void *x
, float*d
, size_t s
) { UNUSED(x
); UNUSED(d
); UNUSED(s
); return -1;}
39 int ad_bitrate_null(void *x
) { UNUSED(x
); return -1;}
42 ad_plugin
const *b
; ///< decoder back-end
43 void *d
; ///< backend data
48 static ad_plugin
const * choose_backend(const char *fn
) {
50 ad_plugin
const *b
=NULL
;
53 val
=adp_get_sndfile()->eval(fn
);
54 if (val
>max
) {max
=val
; b
=adp_get_sndfile();}
57 // NOTE seek is broken for minimp3
58 val
= adp_get_minimp3()->eval(fn
);
59 if (val
> max
) {max
=val
; b
=adp_get_minimp3();}
61 // NOTE dr_mp3 has memory corruption issues
62 val
= adp_get_dr_mp3()->eval(fn
);
63 if (val
> max
) {max
=val
; b
=adp_get_dr_mp3();}
66 val
=adp_get_ffmpeg()->eval(fn
);
67 if (val
>max
) {max
=val
; b
=adp_get_ffmpeg();}
72 void *ad_open(const char *fn
, struct adinfo
*nfo
) {
73 adecoder
*d
= (adecoder
*) calloc(1, sizeof(adecoder
));
76 d
->b
= choose_backend(fn
);
78 dbg(0, "fatal: no decoder backend available");
82 d
->d
= d
->b
->open(fn
, nfo
);
90 int ad_info(void *sf
, struct adinfo
*nfo
) {
91 adecoder
*d
= (adecoder
*) sf
;
93 return d
->b
->info(d
->d
, nfo
);
96 int ad_close(void *sf
) {
97 adecoder
*d
= (adecoder
*) sf
;
99 int rv
= d
->b
->close(d
->d
);
104 int64_t ad_seek(void *sf
, int64_t pos
) {
105 adecoder
*d
= (adecoder
*) sf
;
107 return d
->b
->seek(d
->d
, pos
);
110 ssize_t
ad_read(void *sf
, float* out
, size_t len
){
111 adecoder
*d
= (adecoder
*) sf
;
113 return d
->b
->read(d
->d
, out
, len
);
116 int ad_get_bitrate(void *sf
) {
117 adecoder
*d
= (adecoder
*) sf
;
119 return d
->b
->bitrate(d
->d
);
123 * side-effects: allocates buffer
125 ssize_t
ad_read_mono_dbl(void *sf
, struct adinfo
*nfo
, double* d
, size_t len
){
127 unsigned int chn
= nfo
->channels
;
130 static float *buf
= NULL
;
131 static size_t bufsiz
= 0;
132 if (!buf
|| bufsiz
!= len
*chn
) {
134 buf
= (float*) realloc((void*)buf
, bufsiz
* sizeof(float));
137 len
= ad_read(sf
, buf
, bufsiz
);
139 for (f
=0;f
< (len
/chn
);f
++) {
141 for (c
=0;c
<chn
;c
++) {
150 int ad_finfo (const char *fn
, struct adinfo
*nfo
) {
152 void * sf
= ad_open(fn
, nfo
);
153 return ad_close(sf
)?1:0;
156 void ad_clear_nfo(struct adinfo
*nfo
) {
157 memset(nfo
, 0, sizeof(struct adinfo
));
160 void ad_free_nfo(struct adinfo
*nfo
) {
161 if (nfo
->meta_data
) free(nfo
->meta_data
);
164 void ad_dump_nfo(int dbglvl
, struct adinfo
*nfo
) {
165 dbg(dbglvl
, "sample_rate: %u", nfo
->sample_rate
);
166 dbg(dbglvl
, "channels: %u", nfo
->channels
);
167 dbg(dbglvl
, "length: %"PRIi64
" ms", nfo
->length
);
168 dbg(dbglvl
, "frames: %"PRIi64
, nfo
->frames
);
169 dbg(dbglvl
, "bit_rate: %d", nfo
->bit_rate
);
170 dbg(dbglvl
, "bit_depth: %d", nfo
->bit_depth
);
171 dbg(dbglvl
, "channels: %u", nfo
->channels
);
172 dbg(dbglvl
, "meta-data: %s", nfo
->meta_data
?nfo
->meta_data
:"-");
175 void ad_debug_printf(const char* func
, int level
, const char* format
, ...) {
178 va_start(args
, format
);
179 if (level
<= ad_debug_level
) {
180 fprintf(stderr
, "%s(): ", func
);
181 vfprintf(stderr
, format
, args
);
182 fprintf(stderr
, "\n");
187 void ad_set_debuglevel(int lvl
) {
188 ad_debug_level
= lvl
;
189 if (ad_debug_level
<-1) ad_debug_level
=-1;
190 if (ad_debug_level
>3) ad_debug_level
=3;