14
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
13
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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.
21
* OggFLAC support (half-stolen from flac_plugin.c :))
22
24
#include "_flac_common.h"
23
25
#include "_ogg_common.h"
25
28
#include <OggFLAC/seekable_stream_decoder.h>
26
30
#include <unistd.h>
28
static void oggflac_cleanup(FlacData * data,
32
static void oggflac_cleanup(struct flac_data *data,
29
33
OggFLAC__SeekableStreamDecoder * decoder)
31
if (data->replayGainInfo)
32
replay_gain_info_free(data->replayGainInfo);
35
if (data->replay_gain_info)
36
replay_gain_info_free(data->replay_gain_info);
34
38
OggFLAC__seekable_stream_decoder_delete(decoder);
37
static OggFLAC__SeekableStreamDecoderReadStatus of_read_cb(mpd_unused const
41
static OggFLAC__SeekableStreamDecoderReadStatus of_read_cb(G_GNUC_UNUSED const
38
42
OggFLAC__SeekableStreamDecoder
44
FlacData *data = (FlacData *) fdata;
48
struct flac_data *data = (struct flac_data *) fdata;
47
r = decoder_read(data->decoder, data->inStream, (void *)buf, *bytes);
51
r = decoder_read(data->decoder, data->input_stream,
50
if (r == 0 && !input_stream_eof(data->inStream) &&
55
if (r == 0 && !input_stream_eof(data->input_stream) &&
51
56
decoder_get_command(data->decoder) == DECODE_COMMAND_NONE)
52
57
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
54
59
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
57
static OggFLAC__SeekableStreamDecoderSeekStatus of_seek_cb(mpd_unused const
62
static OggFLAC__SeekableStreamDecoderSeekStatus of_seek_cb(G_GNUC_UNUSED const
58
63
OggFLAC__SeekableStreamDecoder
60
65
FLAC__uint64 offset,
63
FlacData *data = (FlacData *) fdata;
68
struct flac_data *data = (struct flac_data *) fdata;
65
if (!input_stream_seek(data->inStream, offset, SEEK_SET))
70
if (!input_stream_seek(data->input_stream, offset, SEEK_SET))
66
71
return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
68
73
return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
71
static OggFLAC__SeekableStreamDecoderTellStatus of_tell_cb(mpd_unused const
76
static OggFLAC__SeekableStreamDecoderTellStatus of_tell_cb(G_GNUC_UNUSED const
72
77
OggFLAC__SeekableStreamDecoder
75
80
offset, void *fdata)
77
FlacData *data = (FlacData *) fdata;
82
struct flac_data *data = (struct flac_data *) fdata;
79
*offset = (long)(data->inStream->offset);
84
*offset = (long)(data->input_stream->offset);
81
86
return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
84
static OggFLAC__SeekableStreamDecoderLengthStatus of_length_cb(mpd_unused const
89
static OggFLAC__SeekableStreamDecoderLengthStatus of_length_cb(G_GNUC_UNUSED const
85
90
OggFLAC__SeekableStreamDecoder
91
FlacData *data = (FlacData *) fdata;
96
struct flac_data *data = (struct flac_data *) fdata;
93
if (data->inStream->size < 0)
98
if (data->input_stream->size < 0)
94
99
return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
96
*length = (size_t) (data->inStream->size);
101
*length = (size_t) (data->input_stream->size);
98
103
return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
101
static FLAC__bool of_EOF_cb(mpd_unused const OggFLAC__SeekableStreamDecoder * decoder,
106
static FLAC__bool of_EOF_cb(G_GNUC_UNUSED const OggFLAC__SeekableStreamDecoder * decoder,
104
FlacData *data = (FlacData *) fdata;
109
struct flac_data *data = (struct flac_data *) fdata;
106
111
return (decoder_get_command(data->decoder) != DECODE_COMMAND_NONE &&
107
112
decoder_get_command(data->decoder) != DECODE_COMMAND_SEEK) ||
108
input_stream_eof(data->inStream);
113
input_stream_eof(data->input_stream);
111
static void of_error_cb(mpd_unused const OggFLAC__SeekableStreamDecoder * decoder,
116
static void of_error_cb(G_GNUC_UNUSED const OggFLAC__SeekableStreamDecoder * decoder,
112
117
FLAC__StreamDecoderErrorStatus status, void *fdata)
114
flac_error_common_cb("oggflac", status, (FlacData *) fdata);
119
flac_error_common_cb("oggflac", status, (struct flac_data *) fdata);
117
122
static void oggflacPrintErroredState(OggFLAC__SeekableStreamDecoderState state)
148
static FLAC__StreamDecoderWriteStatus oggflacWrite(mpd_unused const
149
OggFLAC__SeekableStreamDecoder
151
const FLAC__Frame * frame,
153
const buf[], void *vdata)
153
static FLAC__StreamDecoderWriteStatus
154
oggflac_write_cb(G_GNUC_UNUSED const OggFLAC__SeekableStreamDecoder *decoder,
155
const FLAC__Frame *frame, const FLAC__int32 *const buf[],
155
FlacData *data = (FlacData *) vdata;
158
struct flac_data *data = (struct flac_data *) vdata;
156
159
FLAC__uint32 samples = frame->header.blocksize;
159
timeChange = ((float)samples) / frame->header.sample_rate;
160
data->time += timeChange;
162
time_change = ((float)samples) / frame->header.sample_rate;
163
data->time += time_change;
162
165
return flac_common_write(data, frame, buf);
165
168
/* used by TagDup */
166
static void of_metadata_dup_cb(mpd_unused const OggFLAC__SeekableStreamDecoder * decoder,
169
static void of_metadata_dup_cb(G_GNUC_UNUSED const OggFLAC__SeekableStreamDecoder * decoder,
167
170
const FLAC__StreamMetadata * block, void *vdata)
169
FlacData *data = (FlacData *) vdata;
172
struct flac_data *data = (struct flac_data *) vdata;
174
assert(data->tag != NULL);
171
176
switch (block->type) {
172
177
case FLAC__METADATA_TYPE_STREAMINFO:
174
data->tag = tag_new();
175
178
data->tag->time = ((float)block->data.stream_info.
177
180
block->data.stream_info.sample_rate + 0.5;
179
182
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
180
copyVorbisCommentBlockToMpdTag(block, data->tag);
183
flac_vorbis_comments_to_tag(data->tag, NULL, block);
186
189
/* used by decode */
187
static void of_metadata_decode_cb(mpd_unused const OggFLAC__SeekableStreamDecoder * dec,
190
static void of_metadata_decode_cb(G_GNUC_UNUSED const OggFLAC__SeekableStreamDecoder * dec,
188
191
const FLAC__StreamMetadata * block,
191
flac_metadata_common_cb(block, (FlacData *) vdata);
194
flac_metadata_common_cb(block, (struct flac_data *) vdata);
194
static OggFLAC__SeekableStreamDecoder
195
* full_decoder_init_and_read_metadata(FlacData * data,
196
unsigned int metadata_only)
197
static OggFLAC__SeekableStreamDecoder *
198
full_decoder_init_and_read_metadata(struct flac_data *data,
199
unsigned int metadata_only)
198
201
OggFLAC__SeekableStreamDecoder *decoder = NULL;
199
202
unsigned int s = 1;
257
260
/* public functions: */
258
static struct tag *oggflac_TagDup(const char *file)
262
oggflac_tag_dup(const char *file)
260
struct input_stream inStream;
264
struct input_stream input_stream;
261
265
OggFLAC__SeekableStreamDecoder *decoder;
266
struct flac_data data;
264
if (!input_stream_open(&inStream, file))
268
if (!input_stream_open(&input_stream, file))
266
if (ogg_stream_type_detect(&inStream) != FLAC) {
267
input_stream_close(&inStream);
270
if (ogg_stream_type_detect(&input_stream) != FLAC) {
271
input_stream_close(&input_stream);
271
init_FlacData(&data, NULL, &inStream);
275
flac_data_init(&data, NULL, &input_stream);
277
data.tag = tag_new();
273
279
/* errors here won't matter,
274
280
* data.tag will be set or unset, that's all we care about */
275
281
decoder = full_decoder_init_and_read_metadata(&data, 1);
277
283
oggflac_cleanup(&data, decoder);
278
input_stream_close(&inStream);
284
input_stream_close(&input_stream);
286
if (!tag_is_defined(data.tag)) {
284
oggflac_decode(struct decoder * mpd_decoder, struct input_stream *inStream)
295
oggflac_decode(struct decoder * mpd_decoder, struct input_stream *input_stream)
286
297
OggFLAC__SeekableStreamDecoder *decoder = NULL;
298
struct flac_data data;
289
if (ogg_stream_type_detect(inStream) != FLAC)
300
if (ogg_stream_type_detect(input_stream) != FLAC)
292
init_FlacData(&data, mpd_decoder, inStream);
303
flac_data_init(&data, mpd_decoder, input_stream);
294
305
if (!(decoder = full_decoder_init_and_read_metadata(&data, 0))) {