1 /*
2  *  A FLAC decoder plugin for the Audacious Media Player
3  *  Copyright (C) 2005 Ralf Ertzinger
4  *
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.
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 General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 #ifndef FLACNG_H
21 #define FLACNG_H
22 
23 #include <FLAC/all.h>
24 
25 #include <libaudcore/i18n.h>
26 #include <libaudcore/plugin.h>
27 
28 class FLACng : public InputPlugin
29 {
30 public:
31     static const char about[];
32     static const char *const exts[];
33     static const char *const mimes[];
34 
35     static constexpr PluginInfo info = {
36         N_("FLAC Decoder"),
37         PACKAGE,
38         about
39     };
40 
FLACng()41     constexpr FLACng() : InputPlugin(info, InputInfo(FlagWritesTag)
42         .with_priority(_AUD_PLUGIN_DEFAULT_PRIO + 1)
43         .with_exts(exts)
44         .with_mimes(mimes)) {}
45 
46     bool init();
47     void cleanup();
48 
49     bool is_our_file(const char *filename, VFSFile &file);
50     bool read_tag(const char *filename, VFSFile &file, Tuple &tuple, Index<char> *image);
51     bool write_tuple(const char *filename, VFSFile &file, const Tuple &tuple);
52     bool play(const char *filename, VFSFile &file);
53 };
54 
55 #define BUFFER_SIZE_SAMP (FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS)
56 #define BUFFER_SIZE_BYTE (BUFFER_SIZE_SAMP * (FLAC__MAX_BITS_PER_SAMPLE/8))
57 
58 #define SAMPLE_SIZE(a) (a == 8 ? 1 : (a == 16 ? 2 : 4))
59 #define SAMPLE_FMT(a) (a == 8 ? FMT_S8 : (a == 16 ? FMT_S16_NE : (a == 24 ? FMT_S24_NE : FMT_S32_NE)))
60 
61 struct callback_info
62 {
63     unsigned bits_per_sample = 0;
64     unsigned sample_rate = 0;
65     unsigned channels = 0;
66     unsigned long total_samples = 0;
67     Index<int32_t> output_buffer;
68     int32_t *write_pointer = nullptr;
69     unsigned buffer_used = 0;
70     VFSFile *fd = nullptr;
71     int bitrate = 0;
72 
alloccallback_info73     void alloc()
74     {
75         output_buffer.resize(BUFFER_SIZE_SAMP);
76         reset();
77     }
78 
resetcallback_info79     void reset()
80     {
81         buffer_used = 0;
82         write_pointer = output_buffer.begin();
83     }
84 };
85 
86 /* metadata.c */
87 bool flac_update_song_tuple(const char *filename, VFSFile &fd, const Tuple &tuple);
88 Index<char> flac_get_image(const char *filename, VFSFile &fd);
89 Tuple flac_probe_for_tuple(const char *filename, VFSFile &fd);
90 
91 /* seekable_stream_callbacks.c */
92 FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
93 FLAC__StreamDecoderSeekStatus seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
94 FLAC__StreamDecoderTellStatus tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
95 FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *client_data);
96 FLAC__StreamDecoderLengthStatus length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
97 FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
98 void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
99 void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
100 
101 /* tools.c */
102 bool read_metadata(FLAC__StreamDecoder* decoder, callback_info* info);
103 
104 #endif
105