/libtunepimp-0.5.3/plugins/flac/flac.cpp
C++ | 232 lines | 166 code | 36 blank | 30 comment | 9 complexity | 28c3a3927a01961df067c58dff7b4e0d MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-3.0, GPL-2.0, LGPL-2.0
1/*----------------------------------------------------------------------------
2
3 libtunepimp -- The MusicBrainz tagging library.
4 Let a thousand taggers bloom!
5
6 Copyright (C) Robert Kaye 2003
7
8 This file is part of libtunepimp.
9
10 libtunepimp is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 libtunepimp is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with libtunepimp; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
24 $Id: flac.cpp 1441 2005-12-18 19:16:49Z luks $
25
26----------------------------------------------------------------------------*/
27
28#include <stdio.h>
29#include <string.h>
30#include <stdlib.h>
31#include <assert.h>
32#include <errno.h>
33#ifdef WIN32
34#include <winsock.h>
35#else
36#include <netinet/in.h>
37#include <sys/param.h>
38#endif
39
40#include "plugin.h"
41#include "flacdecode.h"
42#include "flac_meta.h"
43
44extern "C"
45{
46
47/*-------------------------------------------------------------------------*/
48
49#ifndef WIN32
50 #define initPlugin flacInitPlugin
51#endif
52
53Plugin *initPlugin (void);
54static void flacShutdown (void);
55static const char *flacGetVersion (void);
56static const char *flacGetName (void);
57static int flacGetNumFormats(void);
58static int flacGetFormat (int, char ext[TP_EXTENSION_LEN],
59 char desc[TP_PLUGIN_DESC_LEN], int *functions);
60static const char *flacGetError (void);
61static int flacWriteMetadata(const metadata_t *mdata, const char *fileName, int flags, const char *encoding);
62static int flacReadMetadata (metadata_t *mdata, const char *fileName, int flags, const char *encoding);
63static unsigned long flacGetDuration (const char *file, int flags, const char *encoding);
64static void *flacDecodeStart (const char *file, int flags, const char *encoding);
65static int flacDecodeInfo (void *decode,
66 unsigned long *duration,
67 unsigned int *samplesPerSecond,
68 unsigned int *bitsPerSample,
69 unsigned int *channels);
70static int flacDecodeRead (void *decode, char *data, int maxBytes);
71static void flacDecodeEnd (void *decode);
72
73/*-------------------------------------------------------------------------*/
74
75#define PLUGIN_VERSION "1.0.0"
76#define PLUGIN_NAME "FLAC decoder & metadata reader/writer"
77
78static char *errorString = "";
79
80/*-------------------------------------------------------------------------*/
81
82static Plugin methods =
83{
84 flacShutdown,
85 flacGetVersion,
86 flacGetName,
87 flacGetNumFormats,
88 flacGetFormat,
89 flacGetError,
90 flacReadMetadata,
91 flacWriteMetadata,
92 flacGetDuration,
93 flacDecodeStart,
94 flacDecodeInfo,
95 flacDecodeRead,
96 flacDecodeEnd
97};
98
99/*-------------------------------------------------------------------------*/
100
101Plugin *initPlugin(void)
102{
103 return &methods;
104}
105
106static void flacShutdown(void)
107{
108 if (strlen(errorString))
109 free(errorString);
110}
111
112static const char *flacGetVersion(void)
113{
114 return PLUGIN_VERSION;
115}
116
117static const char *flacGetName(void)
118{
119 return PLUGIN_NAME;
120}
121
122static int flacGetNumFormats(void)
123{
124 return 1;
125}
126
127static int flacGetFormat(int i, char ext[TP_EXTENSION_LEN],
128 char desc[TP_PLUGIN_DESC_LEN], int *functions)
129{
130 if (i > 0)
131 return 0;
132
133 strcpy(ext, ".flac");
134 strcpy(desc, "FLAC Lossless audio format");
135 *functions = TP_PLUGIN_FUNCTION_DECODE | TP_PLUGIN_FUNCTION_METADATA;
136
137 return 1;
138}
139
140static const char *flacGetError(void)
141{
142 return errorString;
143}
144
145static void setError(const string &err)
146{
147 if (err.length())
148 {
149 if (errorString)
150 free(errorString);
151 errorString = strdup(err.c_str());
152 }
153}
154
155static int flacReadMetadata(metadata_t *mdata, const char *fileName, int flags, const char *encoding)
156{
157 Metadata data;
158 FLAC flac(encoding);
159
160 if (flac.read(fileName, data))
161 {
162 data.writeToC(mdata);
163 return 1;
164 }
165 else
166 {
167 string err;
168 flac.getError(err);
169 setError(err);
170 }
171 return 0;
172}
173
174static int flacWriteMetadata(const metadata_t *mdata, const char *fileName, int flags, const char *encoding)
175{
176 Metadata data;
177 FLAC flac(encoding);
178
179 data.readFromC(mdata);
180 int ret = flac.write(fileName, data, (flags & TP_PLUGIN_FLAGS_GENERAL_CLEAR_TAGS) != 0);
181 if (!ret)
182 {
183 string err;
184 flac.getError(err);
185 setError(err);
186 }
187 return ret;
188}
189
190static unsigned long flacGetDuration(const char *fileName, int flags, const char *encoding)
191{
192 FlacDecode *decode;
193 unsigned long duration;
194 unsigned int samplesPerSecond, bitsPerSample, channels;
195
196 decode = new FlacDecode(fileName, encoding);
197 if (!decode)
198 return 0;
199
200 if (!decode->getInfo(duration, samplesPerSecond, bitsPerSample, channels))
201 duration = 0;
202
203 delete decode;
204
205 return duration;
206}
207
208static void *flacDecodeStart(const char *fileName, int flags, const char *encoding)
209{
210 return (void *)new FlacDecode(fileName, encoding);
211}
212
213static int flacDecodeInfo(void *decode,
214 unsigned long *duration,
215 unsigned int *samplesPerSecond,
216 unsigned int *bitsPerSample,
217 unsigned int *channels)
218{
219 return ((FlacDecode *)decode)->getInfo(*duration, *samplesPerSecond, *bitsPerSample, *channels);
220}
221
222static int flacDecodeRead(void *decode, char *data, int maxBytes)
223{
224 return ((FlacDecode *)decode)->read(data, maxBytes);
225}
226
227static void flacDecodeEnd(void *decode)
228{
229 delete (FlacDecode *)decode;
230}
231
232} // extern "C"