~ubuntu-branches/ubuntu/trusty/flac/trusty-security

« back to all changes in this revision

Viewing changes to src/plugin_xmms/plugin.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc 'HE' Brockschmidt
  • Date: 2008-03-16 18:02:56 UTC
  • mfrom: (1.1.5 upstream) (8.1.2 gutsy)
  • Revision ID: james.westby@ubuntu.com-20080316180256-qhf3wk704rp165pm
Tags: 1.2.1-1.2
* Non-maintainer upload.
* Fix gcc-4.3 FTBFS, patch by KiBi (Closes: #455304)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* libxmms-flac - XMMS FLAC input plugin
2
 
 * Copyright (C) 2000,2001,2002,2003,2004,2005  Josh Coalson
 
2
 * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or
5
5
 * modify it under the terms of the GNU General Public License
16
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
17
 */
18
18
 
 
19
#if HAVE_CONFIG_H
 
20
#  include <config.h>
 
21
#endif
 
22
 
 
23
#include <limits.h>
19
24
#include <pthread.h>
20
25
#include <stdlib.h>
21
26
#include <string.h>
30
35
#include <xmms/configfile.h>
31
36
#include <xmms/titlestring.h>
32
37
 
33
 
#ifdef HAVE_CONFIG_H
34
 
#include <config.h>
35
 
#endif
36
 
 
37
38
#ifdef HAVE_LANGINFO_CODESET
38
39
#include <langinfo.h>
39
40
#endif
52
53
#endif
53
54
#define min(x,y) ((x)<(y)?(x):(y))
54
55
 
55
 
/* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
56
 
#ifdef _MSC_VER
57
 
#define FLAC__U64L(x) x
58
 
#else
59
 
#define FLAC__U64L(x) x##LLU
60
 
#endif
61
 
 
62
56
extern void FLAC_XMMS__file_info_box(char *filename);
63
57
 
64
58
typedef struct {
65
59
        FLAC__bool abort_flag;
66
60
        FLAC__bool is_playing;
 
61
        FLAC__bool is_http_source;
67
62
        FLAC__bool eof;
68
63
        FLAC__bool play_thread_open; /* if true, is_playing must also be true */
69
 
        unsigned total_samples;
 
64
        FLAC__uint64 total_samples;
70
65
        unsigned bits_per_sample;
71
66
        unsigned channels;
72
67
        unsigned sample_rate;
73
 
        unsigned length_in_msec;
 
68
        int length_in_msec; /* int (instead of FLAC__uint64) only because that's what XMMS uses; seeking won't work right if this maxes out */
74
69
        gchar *title;
75
70
        AFormat sample_format;
76
71
        unsigned sample_format_bytes_per_sample;
78
73
        FLAC__bool has_replaygain;
79
74
        double replay_scale;
80
75
        DitherContext dither_context;
81
 
} file_info_struct;
82
 
 
83
 
typedef FLAC__StreamDecoderWriteStatus (*WriteCallback) (const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
84
 
typedef void (*MetadataCallback) (const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
85
 
typedef void (*ErrorCallback) (const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
86
 
 
87
 
typedef struct {
88
 
        FLAC__bool seekable;
89
 
        void* (*new_decoder) (void);
90
 
        FLAC__bool (*set_md5_checking) (void *decoder, FLAC__bool value);
91
 
        FLAC__bool (*set_source) (void *decoder, const char* source);
92
 
        FLAC__bool (*set_metadata_ignore_all) (void *decoder);
93
 
        FLAC__bool (*set_metadata_respond) (void *decoder, FLAC__MetadataType type);
94
 
        FLAC__bool (*set_write_callback) (void *decoder, WriteCallback value);
95
 
        FLAC__bool (*set_metadata_callback) (void *decoder, MetadataCallback value);
96
 
        FLAC__bool (*set_error_callback) (void *decoder, ErrorCallback value);
97
 
        FLAC__bool (*set_client_data) (void *decoder, void *value);
98
 
        FLAC__bool (*decoder_init) (void *decoder);
99
 
        void (*safe_decoder_finish) (void *decoder);
100
 
        void (*safe_decoder_delete) (void *decoder);
101
 
        FLAC__bool (*process_until_end_of_metadata) (void *decoder);
102
 
        FLAC__bool (*process_single) (void *decoder);
103
 
        FLAC__bool (*is_eof) (void *decoder);
104
 
} decoder_funcs_t;
105
 
 
106
 
#define NUM_DECODER_TYPES 2
107
 
typedef enum {
108
 
        DECODER_FILE,
109
 
        DECODER_HTTP
110
 
} decoder_t;
111
 
 
112
 
static void FLAC_XMMS__init();
 
76
} stream_data_struct;
 
77
 
 
78
static void FLAC_XMMS__init(void);
113
79
static int  FLAC_XMMS__is_our_file(char *filename);
114
80
static void FLAC_XMMS__play_file(char *filename);
115
 
static void FLAC_XMMS__stop();
 
81
static void FLAC_XMMS__stop(void);
116
82
static void FLAC_XMMS__pause(short p);
117
83
static void FLAC_XMMS__seek(int time);
118
 
static int  FLAC_XMMS__get_time();
119
 
static void FLAC_XMMS__cleanup();
 
84
static int  FLAC_XMMS__get_time(void);
 
85
static void FLAC_XMMS__cleanup(void);
120
86
static void FLAC_XMMS__get_song_info(char *filename, char **title, int *length);
121
87
 
122
88
static void *play_loop_(void *arg);
123
89
 
124
 
static FLAC__bool safe_decoder_init_(const char *filename, void **decoderp, decoder_funcs_t const ** fnsp);
125
 
static void file_decoder_safe_decoder_finish_(void *decoder);
126
 
static void file_decoder_safe_decoder_delete_(void *decoder);
127
 
static FLAC__StreamDecoderWriteStatus write_callback_(const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
128
 
static void metadata_callback_(const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
129
 
static void error_callback_(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
 
90
static FLAC__bool safe_decoder_init_(const char *filename, FLAC__StreamDecoder *decoder);
 
91
static void safe_decoder_finish_(FLAC__StreamDecoder *decoder);
 
92
static void safe_decoder_delete_(FLAC__StreamDecoder *decoder);
130
93
 
131
 
static void init_decoder_func_tables();
132
 
static decoder_t source_to_decoder_type (const char *source);
 
94
static FLAC__StreamDecoderReadStatus http_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
 
95
static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
 
96
static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
 
97
static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
133
98
 
134
99
InputPlugin flac_ip =
135
100
{
164
129
static FLAC__byte sample_buffer_[SAMPLE_BUFFER_SIZE];
165
130
static unsigned sample_buffer_first_, sample_buffer_last_;
166
131
 
167
 
static void *decoder_ = 0;
168
 
static file_info_struct file_info_;
 
132
static FLAC__StreamDecoder *decoder_ = 0;
 
133
static stream_data_struct stream_data_;
169
134
static pthread_t decode_thread_;
170
135
static FLAC__bool audio_error_ = false;
171
136
static FLAC__bool is_big_endian_host_;
175
140
#define BITRATE_HIST_SIZE 50
176
141
static unsigned bitrate_history_[BITRATE_HIST_SIZE];
177
142
 
178
 
/* A table of sets of decoder functions, indexed by decoder_t */
179
 
static const decoder_funcs_t* DECODER_FUNCS[NUM_DECODER_TYPES];
180
 
 
181
 
static decoder_funcs_t const * decoder_func_table_;
182
 
 
183
 
 
184
 
InputPlugin *get_iplugin_info()
 
143
 
 
144
InputPlugin *get_iplugin_info(void)
185
145
{
186
146
        flac_ip.description = g_strdup_printf("Reference FLAC Player v%s", FLAC__VERSION_STRING);
187
147
        return &flac_ip;
189
149
 
190
150
void set_track_info(const char* title, int length_in_msec)
191
151
{
192
 
        if (file_info_.is_playing) {
193
 
                flac_ip.set_info((char*) title, length_in_msec, file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample, file_info_.sample_rate, file_info_.channels);
 
152
        if (stream_data_.is_playing) {
 
153
                flac_ip.set_info((char*) title, length_in_msec, stream_data_.sample_rate * stream_data_.channels * stream_data_.bits_per_sample, stream_data_.sample_rate, stream_data_.channels);
194
154
        }
195
155
}
196
156
 
197
 
static gchar* homedir()
 
157
static gchar* homedir(void)
198
158
{
199
159
        gchar *result;
200
160
        char *env_home = getenv("HOME");
212
172
        return result;
213
173
}
214
174
 
215
 
void FLAC_XMMS__init()
 
175
static FLAC__bool is_http_source(const char *source)
 
176
{
 
177
        return 0 == strncasecmp(source, "http://", 7);
 
178
}
 
179
 
 
180
void FLAC_XMMS__init(void)
216
181
{
217
182
        ConfigFile *cfg;
218
183
        FLAC__uint32 test = 1;
220
185
        is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
221
186
 
222
187
        flac_cfg.title.tag_override = FALSE;
223
 
        g_free(flac_cfg.title.tag_format);
 
188
        if (flac_cfg.title.tag_format)
 
189
                g_free(flac_cfg.title.tag_format);
224
190
        flac_cfg.title.convert_char_set = FALSE;
225
191
 
226
192
        cfg = xmms_cfg_open_default_file();
262
228
        xmms_cfg_read_int(cfg, "flac", "stream.http_buffer_size", &flac_cfg.stream.http_buffer_size);
263
229
        xmms_cfg_read_int(cfg, "flac", "stream.http_prebuffer", &flac_cfg.stream.http_prebuffer);
264
230
        xmms_cfg_read_boolean(cfg, "flac", "stream.use_proxy", &flac_cfg.stream.use_proxy);
265
 
        xmms_cfg_read_string(cfg, "flac", "stream.proxy_host", &flac_cfg.stream.proxy_host);
 
231
        if(flac_cfg.stream.proxy_host)
 
232
                g_free(flac_cfg.stream.proxy_host);
 
233
        if(!xmms_cfg_read_string(cfg, "flac", "stream.proxy_host", &flac_cfg.stream.proxy_host))
 
234
                flac_cfg.stream.proxy_host = g_strdup("");
266
235
        xmms_cfg_read_int(cfg, "flac", "stream.proxy_port", &flac_cfg.stream.proxy_port);
267
236
        xmms_cfg_read_boolean(cfg, "flac", "stream.proxy_use_auth", &flac_cfg.stream.proxy_use_auth);
 
237
        if(flac_cfg.stream.proxy_user)
 
238
                g_free(flac_cfg.stream.proxy_user);
 
239
        flac_cfg.stream.proxy_user = NULL;
268
240
        xmms_cfg_read_string(cfg, "flac", "stream.proxy_user", &flac_cfg.stream.proxy_user);
 
241
        if(flac_cfg.stream.proxy_pass)
 
242
                g_free(flac_cfg.stream.proxy_pass);
 
243
        flac_cfg.stream.proxy_pass = NULL;
269
244
        xmms_cfg_read_string(cfg, "flac", "stream.proxy_pass", &flac_cfg.stream.proxy_pass);
270
245
        xmms_cfg_read_boolean(cfg, "flac", "stream.save_http_stream", &flac_cfg.stream.save_http_stream);
271
 
        if (!xmms_cfg_read_string(cfg, "flac", "stream.save_http_path", &flac_cfg.stream.save_http_path) ||
272
 
                 ! *flac_cfg.stream.save_http_path) {
 
246
        if (flac_cfg.stream.save_http_path)
 
247
                g_free (flac_cfg.stream.save_http_path);
 
248
        if (!xmms_cfg_read_string(cfg, "flac", "stream.save_http_path", &flac_cfg.stream.save_http_path) || ! *flac_cfg.stream.save_http_path) {
273
249
                if (flac_cfg.stream.save_http_path)
274
250
                        g_free (flac_cfg.stream.save_http_path);
275
251
                flac_cfg.stream.save_http_path = homedir();
277
253
        xmms_cfg_read_boolean(cfg, "flac", "stream.cast_title_streaming", &flac_cfg.stream.cast_title_streaming);
278
254
        xmms_cfg_read_boolean(cfg, "flac", "stream.use_udp_channel", &flac_cfg.stream.use_udp_channel);
279
255
 
280
 
        init_decoder_func_tables();
281
 
        decoder_func_table_ = DECODER_FUNCS [DECODER_FILE];
282
 
        decoder_ = decoder_func_table_ -> new_decoder();
 
256
        decoder_ = FLAC__stream_decoder_new();
283
257
 
284
258
        xmms_cfg_free(cfg);
285
259
}
301
275
 
302
276
        sample_buffer_first_ = sample_buffer_last_ = 0;
303
277
        audio_error_ = false;
304
 
        file_info_.abort_flag = false;
305
 
        file_info_.is_playing = false;
306
 
        file_info_.eof = false;
307
 
        file_info_.play_thread_open = false;
308
 
        file_info_.has_replaygain = false;
 
278
        stream_data_.abort_flag = false;
 
279
        stream_data_.is_playing = false;
 
280
        stream_data_.is_http_source = is_http_source(filename);
 
281
        stream_data_.eof = false;
 
282
        stream_data_.play_thread_open = false;
 
283
        stream_data_.has_replaygain = false;
309
284
 
310
 
        if (source_to_decoder_type (filename) == DECODER_FILE) {
 
285
        if(!is_http_source(filename)) {
311
286
                if(0 == (f = fopen(filename, "r")))
312
287
                        return;
313
288
                fclose(f);
316
291
        if(decoder_ == 0)
317
292
                return;
318
293
 
319
 
        if(!safe_decoder_init_(filename, &decoder_, &decoder_func_table_))
 
294
        if(!safe_decoder_init_(filename, decoder_))
320
295
                return;
321
296
 
322
 
        if(file_info_.has_replaygain && flac_cfg.output.replaygain.enable) {
 
297
        if(stream_data_.has_replaygain && flac_cfg.output.replaygain.enable) {
323
298
                if(flac_cfg.output.resolution.replaygain.bps_out == 8) {
324
 
                        file_info_.sample_format = FMT_U8;
325
 
                        file_info_.sample_format_bytes_per_sample = 1;
 
299
                        stream_data_.sample_format = FMT_U8;
 
300
                        stream_data_.sample_format_bytes_per_sample = 1;
326
301
                }
327
302
                else if(flac_cfg.output.resolution.replaygain.bps_out == 16) {
328
 
                        file_info_.sample_format = (is_big_endian_host_) ? FMT_S16_BE : FMT_S16_LE;
329
 
                        file_info_.sample_format_bytes_per_sample = 2;
 
303
                        stream_data_.sample_format = (is_big_endian_host_) ? FMT_S16_BE : FMT_S16_LE;
 
304
                        stream_data_.sample_format_bytes_per_sample = 2;
330
305
                }
331
306
                else {
332
307
                        /*@@@ need some error here like wa2: MessageBox(mod_.hMainWindow, "ERROR: plugin can only handle 8/16-bit samples\n", "ERROR: plugin can only handle 8/16-bit samples", 0); */
333
308
                        fprintf(stderr, "libxmms-flac: can't handle %d bit output\n", flac_cfg.output.resolution.replaygain.bps_out);
334
 
                        decoder_func_table_ -> safe_decoder_finish(decoder_);
 
309
                        safe_decoder_finish_(decoder_);
335
310
                        return;
336
311
                }
337
312
        }
338
313
        else {
339
 
                if(file_info_.bits_per_sample == 8) {
340
 
                        file_info_.sample_format = FMT_U8;
341
 
                        file_info_.sample_format_bytes_per_sample = 1;
 
314
                if(stream_data_.bits_per_sample == 8) {
 
315
                        stream_data_.sample_format = FMT_U8;
 
316
                        stream_data_.sample_format_bytes_per_sample = 1;
342
317
                }
343
 
                else if(file_info_.bits_per_sample == 16 || (file_info_.bits_per_sample == 24 && flac_cfg.output.resolution.normal.dither_24_to_16)) {
344
 
                        file_info_.sample_format = (is_big_endian_host_) ? FMT_S16_BE : FMT_S16_LE;
345
 
                        file_info_.sample_format_bytes_per_sample = 2;
 
318
                else if(stream_data_.bits_per_sample == 16 || (stream_data_.bits_per_sample == 24 && flac_cfg.output.resolution.normal.dither_24_to_16)) {
 
319
                        stream_data_.sample_format = (is_big_endian_host_) ? FMT_S16_BE : FMT_S16_LE;
 
320
                        stream_data_.sample_format_bytes_per_sample = 2;
346
321
                }
347
322
                else {
348
323
                        /*@@@ need some error here like wa2: MessageBox(mod_.hMainWindow, "ERROR: plugin can only handle 8/16-bit samples\n", "ERROR: plugin can only handle 8/16-bit samples", 0); */
349
 
                        fprintf(stderr, "libxmms-flac: can't handle %d bit output\n", file_info_.bits_per_sample);
350
 
                        decoder_func_table_ -> safe_decoder_finish(decoder_);
 
324
                        fprintf(stderr, "libxmms-flac: can't handle %d bit output\n", stream_data_.bits_per_sample);
 
325
                        safe_decoder_finish_(decoder_);
351
326
                        return;
352
327
                }
353
328
        }
354
 
        FLAC__replaygain_synthesis__init_dither_context(&file_info_.dither_context, file_info_.sample_format_bytes_per_sample * 8, flac_cfg.output.resolution.replaygain.noise_shaping);
355
 
        file_info_.is_playing = true;
 
329
        FLAC__replaygain_synthesis__init_dither_context(&stream_data_.dither_context, stream_data_.sample_format_bytes_per_sample * 8, flac_cfg.output.resolution.replaygain.noise_shaping);
 
330
        stream_data_.is_playing = true;
356
331
 
357
 
        if(flac_ip.output->open_audio(file_info_.sample_format, file_info_.sample_rate, file_info_.channels) == 0) {
 
332
        if(flac_ip.output->open_audio(stream_data_.sample_format, stream_data_.sample_rate, stream_data_.channels) == 0) {
358
333
                audio_error_ = true;
359
 
                decoder_func_table_ -> safe_decoder_finish(decoder_);
 
334
                safe_decoder_finish_(decoder_);
360
335
                return;
361
336
        }
362
337
 
363
 
        file_info_.title = flac_format_song_title(filename);
364
 
        flac_ip.set_info(file_info_.title, file_info_.length_in_msec, file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample, file_info_.sample_rate, file_info_.channels);
 
338
        stream_data_.title = flac_format_song_title(filename);
 
339
        flac_ip.set_info(stream_data_.title, stream_data_.length_in_msec, stream_data_.sample_rate * stream_data_.channels * stream_data_.bits_per_sample, stream_data_.sample_rate, stream_data_.channels);
365
340
 
366
 
        file_info_.seek_to_in_sec = -1;
367
 
        file_info_.play_thread_open = true;
 
341
        stream_data_.seek_to_in_sec = -1;
 
342
        stream_data_.play_thread_open = true;
368
343
        pthread_create(&decode_thread_, NULL, play_loop_, NULL);
369
344
}
370
345
 
371
 
void FLAC_XMMS__stop()
 
346
void FLAC_XMMS__stop(void)
372
347
{
373
 
        if(file_info_.is_playing) {
374
 
                file_info_.is_playing = false;
375
 
                if(file_info_.play_thread_open) {
376
 
                        file_info_.play_thread_open = false;
 
348
        if(stream_data_.is_playing) {
 
349
                stream_data_.is_playing = false;
 
350
                if(stream_data_.play_thread_open) {
 
351
                        stream_data_.play_thread_open = false;
377
352
                        pthread_join(decode_thread_, NULL);
378
353
                }
379
354
                flac_ip.output->close_audio();
380
 
                decoder_func_table_ -> safe_decoder_finish (decoder_);
 
355
                safe_decoder_finish_(decoder_);
381
356
        }
382
357
}
383
358
 
388
363
 
389
364
void FLAC_XMMS__seek(int time)
390
365
{
391
 
        if (decoder_func_table_->seekable) {
392
 
                file_info_.seek_to_in_sec = time;
393
 
                file_info_.eof = false;
 
366
        if(!stream_data_.is_http_source) {
 
367
                stream_data_.seek_to_in_sec = time;
 
368
                stream_data_.eof = false;
394
369
 
395
 
                while(file_info_.seek_to_in_sec != -1)
 
370
                while(stream_data_.seek_to_in_sec != -1)
396
371
                        xmms_usleep(10000);
397
372
        }
398
373
}
399
374
 
400
 
int FLAC_XMMS__get_time()
 
375
int FLAC_XMMS__get_time(void)
401
376
{
402
377
        if(audio_error_)
403
378
                return -2;
404
 
        if(!file_info_.is_playing || (file_info_.eof && !flac_ip.output->buffer_playing()))
 
379
        if(!stream_data_.is_playing || (stream_data_.eof && !flac_ip.output->buffer_playing()))
405
380
                return -1;
406
381
        else
407
382
                return flac_ip.output->output_time();
408
383
}
409
384
 
410
 
void FLAC_XMMS__cleanup()
 
385
void FLAC_XMMS__cleanup(void)
411
386
{
412
 
        decoder_func_table_ -> safe_decoder_delete(decoder_);
 
387
        safe_decoder_delete_(decoder_);
413
388
        decoder_ = 0;
414
389
}
415
390
 
423
398
        if(!FLAC__metadata_get_streaminfo(filename, &streaminfo)) {
424
399
                /* @@@ how to report the error? */
425
400
                if(title) {
426
 
                        if (source_to_decoder_type (filename) == DECODER_FILE) {
 
401
                        if (!is_http_source(filename)) {
427
402
                                static const char *errtitle = "Invalid FLAC File: ";
428
 
                                *title = g_malloc(strlen(errtitle) + 1 + strlen(filename) + 1 + 1);
429
 
                                sprintf(*title, "%s\"%s\"", errtitle, filename);
 
403
                                if(strlen(errtitle) + 1 + strlen(filename) + 1 + 1 < strlen(filename)) { /* overflow check */
 
404
                                        *title = NULL;
 
405
                                }
 
406
                                else {
 
407
                                        *title = g_malloc(strlen(errtitle) + 1 + strlen(filename) + 1 + 1);
 
408
                                        sprintf(*title, "%s\"%s\"", errtitle, filename);
 
409
                                }
430
410
                        } else {
431
411
                                *title = NULL;
432
412
                        }
439
419
        if(title) {
440
420
                *title = flac_format_song_title(filename);
441
421
        }
442
 
        if(length_in_msec)
443
 
                *length_in_msec = (unsigned)((double)streaminfo.data.stream_info.total_samples / (double)streaminfo.data.stream_info.sample_rate * 1000.0 + 0.5);
 
422
        if(length_in_msec) {
 
423
                FLAC__uint64 l = (FLAC__uint64)((double)streaminfo.data.stream_info.total_samples / (double)streaminfo.data.stream_info.sample_rate * 1000.0 + 0.5);
 
424
                if (l > INT_MAX)
 
425
                        l = INT_MAX;
 
426
                *length_in_msec = (int)l;
 
427
        }
444
428
}
445
429
 
446
430
/***********************************************************************
454
438
 
455
439
        (void)arg;
456
440
 
457
 
        while(file_info_.is_playing) {
458
 
                if(!file_info_.eof) {
 
441
        while(stream_data_.is_playing) {
 
442
                if(!stream_data_.eof) {
459
443
                        while(sample_buffer_last_ - sample_buffer_first_ < SAMPLES_PER_WRITE) {
460
444
                                unsigned s;
461
445
 
462
446
                                s = sample_buffer_last_ - sample_buffer_first_;
463
 
                                if(decoder_func_table_ -> is_eof(decoder_)) {
464
 
                                        file_info_.eof = true;
 
447
                                if(FLAC__stream_decoder_get_state(decoder_) == FLAC__STREAM_DECODER_END_OF_STREAM) {
 
448
                                        stream_data_.eof = true;
465
449
                                        break;
466
450
                                }
467
 
                                else if (!decoder_func_table_ -> process_single(decoder_)) {
 
451
                                else if(!FLAC__stream_decoder_process_single(decoder_)) {
468
452
                                        /*@@@ this should probably be a dialog */
469
453
                                        fprintf(stderr, "libxmms-flac: READ ERROR processing frame\n");
470
 
                                        file_info_.eof = true;
 
454
                                        stream_data_.eof = true;
471
455
                                        break;
472
456
                                }
473
457
                                blocksize = sample_buffer_last_ - sample_buffer_first_ - s;
474
458
                                decode_position_frame_last = decode_position_frame;
475
 
                                if(!decoder_func_table_->seekable || !FLAC__file_decoder_get_decode_position(decoder_, &decode_position_frame))
 
459
                                if(stream_data_.is_http_source || !FLAC__stream_decoder_get_decode_position(decoder_, &decode_position_frame))
476
460
                                        decode_position_frame = 0;
477
461
                        }
478
462
                        if(sample_buffer_last_ - sample_buffer_first_ > 0) {
479
463
                                const unsigned n = min(sample_buffer_last_ - sample_buffer_first_, SAMPLES_PER_WRITE);
480
 
                                int bytes = n * file_info_.channels * file_info_.sample_format_bytes_per_sample;
481
 
                                FLAC__byte *sample_buffer_start = sample_buffer_ + sample_buffer_first_ * file_info_.channels * file_info_.sample_format_bytes_per_sample;
 
464
                                int bytes = n * stream_data_.channels * stream_data_.sample_format_bytes_per_sample;
 
465
                                FLAC__byte *sample_buffer_start = sample_buffer_ + sample_buffer_first_ * stream_data_.channels * stream_data_.sample_format_bytes_per_sample;
482
466
                                unsigned written_time, bh_index_w;
483
467
                                FLAC__uint64 decode_position;
484
468
 
485
469
                                sample_buffer_first_ += n;
486
 
                                flac_ip.add_vis_pcm(flac_ip.output->written_time(), file_info_.sample_format, file_info_.channels, bytes, sample_buffer_start);
487
 
                                while(flac_ip.output->buffer_free() < (int)bytes && file_info_.is_playing && file_info_.seek_to_in_sec == -1)
 
470
                                flac_ip.add_vis_pcm(flac_ip.output->written_time(), stream_data_.sample_format, stream_data_.channels, bytes, sample_buffer_start);
 
471
                                while(flac_ip.output->buffer_free() < (int)bytes && stream_data_.is_playing && stream_data_.seek_to_in_sec == -1)
488
472
                                        xmms_usleep(10000);
489
 
                                if(file_info_.is_playing && file_info_.seek_to_in_sec == -1)
 
473
                                if(stream_data_.is_playing && stream_data_.seek_to_in_sec == -1)
490
474
                                        flac_ip.output->write_audio(sample_buffer_start, bytes);
491
475
 
492
476
                                /* compute current bitrate */
499
483
                                        bitrate_history_[(bh_index_w + BITRATE_HIST_SIZE - 1) % BITRATE_HIST_SIZE] =
500
484
                                                decode_position > decode_position_last && written_time > written_time_last ?
501
485
                                                        8000 * (decode_position - decode_position_last) / (written_time - written_time_last) :
502
 
                                                        file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample;
 
486
                                                        stream_data_.sample_rate * stream_data_.channels * stream_data_.bits_per_sample;
503
487
                                        decode_position_last = decode_position;
504
488
                                        written_time_last = written_time;
505
489
                                }
506
490
                        }
507
491
                        else {
508
 
                                file_info_.eof = true;
 
492
                                stream_data_.eof = true;
509
493
                                xmms_usleep(10000);
510
494
                        }
511
495
                }
512
496
                else
513
497
                        xmms_usleep(10000);
514
 
                if(decoder_func_table_->seekable && file_info_.seek_to_in_sec != -1) {
515
 
                        const double distance = (double)file_info_.seek_to_in_sec * 1000.0 / (double)file_info_.length_in_msec;
516
 
                        unsigned target_sample = (unsigned)(distance * (double)file_info_.total_samples);
517
 
                        if(FLAC__file_decoder_seek_absolute(decoder_, (FLAC__uint64)target_sample)) {
518
 
                                flac_ip.output->flush(file_info_.seek_to_in_sec * 1000);
 
498
                if(!stream_data_.is_http_source && stream_data_.seek_to_in_sec != -1) {
 
499
                        const double distance = (double)stream_data_.seek_to_in_sec * 1000.0 / (double)stream_data_.length_in_msec;
 
500
                        FLAC__uint64 target_sample = (FLAC__uint64)(distance * (double)stream_data_.total_samples);
 
501
                        if(stream_data_.total_samples > 0 && target_sample >= stream_data_.total_samples)
 
502
                                target_sample = stream_data_.total_samples - 1;
 
503
                        if(FLAC__stream_decoder_seek_absolute(decoder_, target_sample)) {
 
504
                                flac_ip.output->flush(stream_data_.seek_to_in_sec * 1000);
519
505
                                bh_index_last_w = bh_index_last_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
520
 
                                if(!FLAC__file_decoder_get_decode_position(decoder_, &decode_position_frame))
 
506
                                if(!FLAC__stream_decoder_get_decode_position(decoder_, &decode_position_frame))
521
507
                                        decode_position_frame = 0;
522
 
                                file_info_.seek_to_in_sec = -1;
523
 
                                file_info_.eof = false;
524
 
                                sample_buffer_first_ = sample_buffer_last_ = 0;
525
 
                        }
 
508
                                stream_data_.eof = false;
 
509
                                sample_buffer_first_ = sample_buffer_last_ = 0;
 
510
                        }
 
511
                        else if(FLAC__stream_decoder_get_state(decoder_) == FLAC__STREAM_DECODER_SEEK_ERROR) {
 
512
                                /*@@@ this should probably be a dialog */
 
513
                                fprintf(stderr, "libxmms-flac: SEEK ERROR\n");
 
514
                                FLAC__stream_decoder_flush(decoder_);
 
515
                                stream_data_.eof = false;
 
516
                                sample_buffer_first_ = sample_buffer_last_ = 0;
 
517
                        }
 
518
                        stream_data_.seek_to_in_sec = -1;
526
519
                }
527
520
                else {
528
521
                        /* display the right bitrate from history */
529
522
                        unsigned bh_index_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
530
523
                        if(bh_index_o != bh_index_last_o && bh_index_o != bh_index_last_w && bh_index_o != (bh_index_last_w + 1) % BITRATE_HIST_SIZE) {
531
524
                                bh_index_last_o = bh_index_o;
532
 
                                flac_ip.set_info(file_info_.title, file_info_.length_in_msec, bitrate_history_[bh_index_o], file_info_.sample_rate, file_info_.channels);
 
525
                                flac_ip.set_info(stream_data_.title, stream_data_.length_in_msec, bitrate_history_[bh_index_o], stream_data_.sample_rate, stream_data_.channels);
533
526
                        }
534
527
                }
535
528
        }
536
529
 
537
 
        decoder_func_table_ -> safe_decoder_finish(decoder_);
 
530
        safe_decoder_finish_(decoder_);
538
531
 
539
532
        /* are these two calls necessary? */
540
533
        flac_ip.output->buffer_free();
541
534
        flac_ip.output->buffer_free();
542
535
 
543
 
        g_free(file_info_.title);
 
536
        g_free(stream_data_.title);
544
537
 
545
538
        pthread_exit(NULL);
546
539
        return 0; /* to silence the compiler warning about not returning a value */
547
540
}
548
541
 
549
 
/*********** File decoder functions */
550
 
 
551
 
static FLAC__bool file_decoder_init (void *decoder)
552
 
{
553
 
        return FLAC__file_decoder_init( (FLAC__FileDecoder*) decoder) == FLAC__FILE_DECODER_OK;
554
 
}
555
 
 
556
 
static void file_decoder_safe_decoder_finish_(void *decoder)
557
 
{
558
 
        if(decoder && FLAC__file_decoder_get_state((FLAC__FileDecoder *) decoder) != FLAC__FILE_DECODER_UNINITIALIZED)
559
 
                FLAC__file_decoder_finish((FLAC__FileDecoder *) decoder);
560
 
}
561
 
 
562
 
static void file_decoder_safe_decoder_delete_(void *decoder)
 
542
FLAC__bool safe_decoder_init_(const char *filename, FLAC__StreamDecoder *decoder)
 
543
{
 
544
        if(decoder == 0)
 
545
                return false;
 
546
 
 
547
        safe_decoder_finish_(decoder);
 
548
 
 
549
        FLAC__stream_decoder_set_md5_checking(decoder, false);
 
550
        FLAC__stream_decoder_set_metadata_ignore_all(decoder);
 
551
        FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
 
552
        FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
 
553
        if(stream_data_.is_http_source) {
 
554
                flac_http_open(filename, 0);
 
555
                if(FLAC__stream_decoder_init_stream(decoder, http_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, write_callback_, metadata_callback_, error_callback_, /*client_data=*/&stream_data_) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
 
556
                        return false;
 
557
        }
 
558
        else {
 
559
                if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/&stream_data_) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
 
560
                        return false;
 
561
        }
 
562
 
 
563
        if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
 
564
                return false;
 
565
 
 
566
        return true;
 
567
}
 
568
 
 
569
void safe_decoder_finish_(FLAC__StreamDecoder *decoder)
 
570
{
 
571
        if(decoder && FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_UNINITIALIZED)
 
572
                (void)FLAC__stream_decoder_finish(decoder);
 
573
        if(stream_data_.is_http_source)
 
574
                flac_http_close();
 
575
}
 
576
 
 
577
void safe_decoder_delete_(FLAC__StreamDecoder *decoder)
563
578
{
564
579
        if(decoder) {
565
 
                file_decoder_safe_decoder_finish_(decoder);
566
 
                FLAC__file_decoder_delete( (FLAC__FileDecoder *) decoder);
 
580
                safe_decoder_finish_(decoder);
 
581
                FLAC__stream_decoder_delete(decoder);
567
582
        }
568
583
}
569
584
 
570
 
static FLAC__bool file_decoder_is_eof(void *decoder)
571
 
{
572
 
        return FLAC__file_decoder_get_state((FLAC__FileDecoder *) decoder) == FLAC__FILE_DECODER_END_OF_FILE;
573
 
}
574
 
 
575
 
static const decoder_funcs_t FILE_DECODER_FUNCTIONS = {
576
 
        true,
577
 
        (void* (*) (void)) FLAC__file_decoder_new,
578
 
        (FLAC__bool (*) (void *, FLAC__bool)) FLAC__file_decoder_set_md5_checking,
579
 
        (FLAC__bool (*) (void *, const char*)) FLAC__file_decoder_set_filename,
580
 
        (FLAC__bool (*) (void *)) FLAC__file_decoder_set_metadata_ignore_all,
581
 
        (FLAC__bool (*) (void *, FLAC__MetadataType)) FLAC__file_decoder_set_metadata_respond,
582
 
        (FLAC__bool (*) (void *, WriteCallback)) FLAC__file_decoder_set_write_callback,
583
 
        (FLAC__bool (*) (void *, MetadataCallback)) FLAC__file_decoder_set_metadata_callback,
584
 
        (FLAC__bool (*) (void *, ErrorCallback)) FLAC__file_decoder_set_error_callback,
585
 
        (FLAC__bool (*) (void *, void *)) FLAC__file_decoder_set_client_data,
586
 
        (FLAC__bool (*) (void *)) file_decoder_init,
587
 
        (void (*) (void *)) file_decoder_safe_decoder_finish_,
588
 
        (void (*) (void *)) file_decoder_safe_decoder_delete_,
589
 
        (FLAC__bool (*) (void *)) FLAC__file_decoder_process_until_end_of_metadata,
590
 
        (FLAC__bool (*) (void *)) FLAC__file_decoder_process_single,
591
 
        file_decoder_is_eof
592
 
};
593
 
 
594
 
/*********** HTTP decoder functions */
595
 
 
596
 
static gchar *url_;
597
 
 
598
 
static FLAC__bool http_decoder_set_md5_checking (void *decoder, FLAC__bool value)
599
 
{
600
 
        (void) value;
601
 
        // operation unsupported
602
 
        return FLAC__stream_decoder_get_state ((const FLAC__StreamDecoder *) decoder) ==
603
 
                FLAC__STREAM_DECODER_UNINITIALIZED;
604
 
}
605
 
 
606
 
static FLAC__bool http_decoder_set_url (void *decoder, const char* url)
607
 
{
608
 
        (void) decoder;
609
 
        url_ = g_strdup (url);
610
 
        return true;
611
 
}
612
 
 
613
 
static FLAC__StreamDecoderReadStatus http_decoder_read_callback (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
614
 
{
615
 
        (void) decoder;
616
 
        (void) client_data;
617
 
        *bytes = flac_http_read (buffer, *bytes);
 
585
FLAC__StreamDecoderReadStatus http_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
 
586
{
 
587
        (void)decoder;
 
588
        (void)client_data;
 
589
        *bytes = flac_http_read(buffer, *bytes);
618
590
        return *bytes ? FLAC__STREAM_DECODER_READ_STATUS_CONTINUE : FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
619
591
}
620
592
 
621
 
static FLAC__bool http_decoder_init (void *decoder)
622
 
{
623
 
        flac_http_open (url_, 0);
624
 
        g_free (url_);
625
 
        FLAC__stream_decoder_set_read_callback (decoder, http_decoder_read_callback);
626
 
        return FLAC__stream_decoder_init( (FLAC__StreamDecoder*) decoder) == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;
627
 
}
628
 
 
629
 
static void http_decoder_safe_decoder_finish_(void *decoder)
630
 
{
631
 
        if(decoder && FLAC__stream_decoder_get_state((FLAC__StreamDecoder *) decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) {
632
 
                FLAC__stream_decoder_finish((FLAC__StreamDecoder *) decoder);
633
 
                flac_http_close();
634
 
        }
635
 
}
636
 
 
637
 
static void http_decoder_safe_decoder_delete_(void *decoder)
638
 
{
639
 
        if(decoder) {
640
 
                http_decoder_safe_decoder_finish_(decoder);
641
 
                FLAC__stream_decoder_delete( (FLAC__StreamDecoder *) decoder);
642
 
        }
643
 
}
644
 
 
645
 
static FLAC__bool http_decoder_is_eof(void *decoder)
646
 
{
647
 
        return FLAC__stream_decoder_get_state((FLAC__StreamDecoder *) decoder) == FLAC__STREAM_DECODER_END_OF_STREAM;
648
 
}
649
 
 
650
 
static const decoder_funcs_t HTTP_DECODER_FUNCTIONS = {
651
 
        false,
652
 
        (void* (*) (void)) FLAC__stream_decoder_new,
653
 
        http_decoder_set_md5_checking,
654
 
        (FLAC__bool (*) (void *, const char*)) http_decoder_set_url,
655
 
        (FLAC__bool (*) (void *)) FLAC__stream_decoder_set_metadata_ignore_all,
656
 
        (FLAC__bool (*) (void *, FLAC__MetadataType)) FLAC__stream_decoder_set_metadata_respond,
657
 
        (FLAC__bool (*) (void *, WriteCallback)) FLAC__stream_decoder_set_write_callback,
658
 
        (FLAC__bool (*) (void *, MetadataCallback)) FLAC__stream_decoder_set_metadata_callback,
659
 
        (FLAC__bool (*) (void *, ErrorCallback)) FLAC__stream_decoder_set_error_callback,
660
 
        (FLAC__bool (*) (void *, void *)) FLAC__stream_decoder_set_client_data,
661
 
        (FLAC__bool (*) (void *)) http_decoder_init,
662
 
        (void (*) (void *)) http_decoder_safe_decoder_finish_,
663
 
        (void (*) (void *)) http_decoder_safe_decoder_delete_,
664
 
        (FLAC__bool (*) (void *)) FLAC__stream_decoder_process_until_end_of_metadata,
665
 
        (FLAC__bool (*) (void *)) FLAC__stream_decoder_process_single,
666
 
        http_decoder_is_eof
667
 
};
668
 
 
669
 
static decoder_funcs_t const *decoder_func_table_;
670
 
 
671
 
static void init_decoder_func_tables()
672
 
{
673
 
        DECODER_FUNCS [DECODER_FILE] = & FILE_DECODER_FUNCTIONS;
674
 
        DECODER_FUNCS [DECODER_HTTP] = & HTTP_DECODER_FUNCTIONS;
675
 
}
676
 
 
677
 
static decoder_t source_to_decoder_type (const char *source)
678
 
{
679
 
        return strncasecmp(source, "http://", 7) ? DECODER_FILE : DECODER_HTTP;
680
 
}
681
 
 
682
 
static void change_decoder_if_needed (decoder_t new_decoder_type, void **decoderp, decoder_funcs_t const ** fntabp)
683
 
{
684
 
        const decoder_funcs_t *new_fn_table = DECODER_FUNCS [new_decoder_type];
685
 
        if (*fntabp != new_fn_table) {
686
 
                (*fntabp)->safe_decoder_delete(*decoderp);
687
 
                *fntabp = new_fn_table;
688
 
                *decoderp = new_fn_table -> new_decoder();
689
 
        }
690
 
}
691
 
 
692
 
FLAC__bool safe_decoder_init_(const char *filename, void **decoderp, decoder_funcs_t const ** fntabp)
693
 
{
694
 
        if(decoderp == 0 || *decoderp == 0)
695
 
                return false;
696
 
 
697
 
        (*fntabp)->safe_decoder_finish(*decoderp);
698
 
 
699
 
        change_decoder_if_needed(source_to_decoder_type(filename), decoderp, fntabp);
700
 
 
701
 
        {
702
 
                decoder_funcs_t const *fntab = *fntabp;
703
 
                void *decoder = *decoderp;
704
 
 
705
 
                decoder = *decoderp;
706
 
                fntab = *fntabp;
707
 
 
708
 
                fntab -> set_md5_checking(decoder, false);
709
 
                fntab -> set_source(decoder, filename);
710
 
                fntab -> set_metadata_ignore_all(decoder);
711
 
                fntab -> set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
712
 
                fntab -> set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
713
 
                fntab -> set_write_callback(decoder, write_callback_);
714
 
                fntab -> set_metadata_callback(decoder, metadata_callback_);
715
 
                fntab -> set_error_callback(decoder, error_callback_);
716
 
                fntab -> set_client_data(decoder, &file_info_);
717
 
                if(!fntab -> decoder_init(decoder))
718
 
                        return false;
719
 
 
720
 
                if(!fntab -> process_until_end_of_metadata(decoder))
721
 
                        return false;
722
 
        }
723
 
 
724
 
        return true;
725
 
}
726
 
 
727
 
FLAC__StreamDecoderWriteStatus write_callback_(const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
728
 
{
729
 
        file_info_struct *file_info = (file_info_struct *)client_data;
730
 
        const unsigned channels = file_info->channels, wide_samples = frame->header.blocksize;
731
 
        const unsigned bits_per_sample = file_info->bits_per_sample;
 
593
FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
 
594
{
 
595
        stream_data_struct *stream_data = (stream_data_struct *)client_data;
 
596
        const unsigned channels = stream_data->channels, wide_samples = frame->header.blocksize;
 
597
        const unsigned bits_per_sample = stream_data->bits_per_sample;
732
598
        FLAC__byte *sample_buffer_start;
733
599
 
734
600
        (void)decoder;
735
601
 
736
 
        if(file_info->abort_flag)
 
602
        if(stream_data->abort_flag)
737
603
                return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
738
604
 
739
 
        if((sample_buffer_last_ + wide_samples) > (SAMPLE_BUFFER_SIZE / (channels * file_info->sample_format_bytes_per_sample))) {
740
 
                memmove(sample_buffer_, sample_buffer_ + sample_buffer_first_ * channels * file_info->sample_format_bytes_per_sample, (sample_buffer_last_ - sample_buffer_first_) * channels * file_info->sample_format_bytes_per_sample);
 
605
        if((sample_buffer_last_ + wide_samples) > (SAMPLE_BUFFER_SIZE / (channels * stream_data->sample_format_bytes_per_sample))) {
 
606
                memmove(sample_buffer_, sample_buffer_ + sample_buffer_first_ * channels * stream_data->sample_format_bytes_per_sample, (sample_buffer_last_ - sample_buffer_first_) * channels * stream_data->sample_format_bytes_per_sample);
741
607
                sample_buffer_last_ -= sample_buffer_first_;
742
608
                sample_buffer_first_ = 0;
743
609
        }
744
 
        sample_buffer_start = sample_buffer_ + sample_buffer_last_ * channels * file_info->sample_format_bytes_per_sample;
745
 
        if(file_info->has_replaygain && flac_cfg.output.replaygain.enable) {
 
610
        sample_buffer_start = sample_buffer_ + sample_buffer_last_ * channels * stream_data->sample_format_bytes_per_sample;
 
611
        if(stream_data->has_replaygain && flac_cfg.output.replaygain.enable) {
746
612
                FLAC__replaygain_synthesis__apply_gain(
747
613
                                sample_buffer_start,
748
614
                                !is_big_endian_host_,
749
 
                                file_info->sample_format_bytes_per_sample == 1, /* unsigned_data_out */
 
615
                                stream_data->sample_format_bytes_per_sample == 1, /* unsigned_data_out */
750
616
                                buffer,
751
617
                                wide_samples,
752
618
                                channels,
753
619
                                bits_per_sample,
754
 
                                file_info->sample_format_bytes_per_sample * 8,
755
 
                                file_info->replay_scale,
 
620
                                stream_data->sample_format_bytes_per_sample * 8,
 
621
                                stream_data->replay_scale,
756
622
                                flac_cfg.output.replaygain.hard_limit,
757
623
                                flac_cfg.output.resolution.replaygain.dither,
758
 
                                &file_info->dither_context
 
624
                                &stream_data->dither_context
759
625
                );
760
626
        }
761
627
        else if(is_big_endian_host_) {
765
631
                        wide_samples,
766
632
                        channels,
767
633
                        bits_per_sample,
768
 
                        file_info->sample_format_bytes_per_sample * 8
 
634
                        stream_data->sample_format_bytes_per_sample * 8
769
635
                );
770
636
        }
771
637
        else {
775
641
                        wide_samples,
776
642
                        channels,
777
643
                        bits_per_sample,
778
 
                        file_info->sample_format_bytes_per_sample * 8
 
644
                        stream_data->sample_format_bytes_per_sample * 8
779
645
                );
780
646
        }
781
647
 
784
650
        return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
785
651
}
786
652
 
787
 
void metadata_callback_(const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
 
653
void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
788
654
{
789
 
        file_info_struct *file_info = (file_info_struct *)client_data;
 
655
        stream_data_struct *stream_data = (stream_data_struct *)client_data;
790
656
        (void)decoder;
791
657
        if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
792
 
                FLAC__ASSERT(metadata->data.stream_info.total_samples < FLAC__U64L(0x100000000)); /* this plugin can only handle < 4 gigasamples */
793
 
                file_info->total_samples = (unsigned)(metadata->data.stream_info.total_samples&0xffffffff);
794
 
                file_info->bits_per_sample = metadata->data.stream_info.bits_per_sample;
795
 
                file_info->channels = metadata->data.stream_info.channels;
796
 
                file_info->sample_rate = metadata->data.stream_info.sample_rate;
797
 
                file_info->length_in_msec = (unsigned)((double)file_info->total_samples / (double)file_info->sample_rate * 1000.0 + 0.5);
 
658
                stream_data->total_samples = metadata->data.stream_info.total_samples;
 
659
                stream_data->bits_per_sample = metadata->data.stream_info.bits_per_sample;
 
660
                stream_data->channels = metadata->data.stream_info.channels;
 
661
                stream_data->sample_rate = metadata->data.stream_info.sample_rate;
 
662
                {
 
663
                        FLAC__uint64 l = (FLAC__uint64)((double)stream_data->total_samples / (double)stream_data->sample_rate * 1000.0 + 0.5);
 
664
                        if (l > INT_MAX)
 
665
                                l = INT_MAX;
 
666
                        stream_data->length_in_msec = (int)l;
 
667
                }
798
668
        }
799
669
        else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
800
 
                double gain, peak;
801
 
                if(grabbag__replaygain_load_from_vorbiscomment(metadata, flac_cfg.output.replaygain.album_mode, &gain, &peak)) {
802
 
                        file_info->has_replaygain = true;
803
 
                        file_info->replay_scale = grabbag__replaygain_compute_scale_factor(peak, gain, (double)flac_cfg.output.replaygain.preamp, /*prevent_clipping=*/!flac_cfg.output.replaygain.hard_limit);
 
670
                double reference, gain, peak;
 
671
                if(grabbag__replaygain_load_from_vorbiscomment(metadata, flac_cfg.output.replaygain.album_mode, /*strict=*/false, &reference, &gain, &peak)) {
 
672
                        stream_data->has_replaygain = true;
 
673
                        stream_data->replay_scale = grabbag__replaygain_compute_scale_factor(peak, gain, (double)flac_cfg.output.replaygain.preamp, /*prevent_clipping=*/!flac_cfg.output.replaygain.hard_limit);
804
674
                }
805
675
        }
806
676
}
807
677
 
808
 
void error_callback_(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
 
678
void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
809
679
{
810
 
        file_info_struct *file_info = (file_info_struct *)client_data;
 
680
        stream_data_struct *stream_data = (stream_data_struct *)client_data;
811
681
        (void)decoder;
812
682
        if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC)
813
 
                file_info->abort_flag = true;
 
683
                stream_data->abort_flag = true;
814
684
}