~ubuntu-branches/ubuntu/hoary/flac/hoary

« back to all changes in this revision

Viewing changes to src/plugin_xmms/plugin.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Zimmerman
  • Date: 2004-04-16 15:14:31 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040416151431-eyloggqxpwbwpogz
Tags: 1.1.0-11
Ensure that libFLAC is linked with -lm on all architectures, and
regardless of whether nasm is present

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  Josh Coalson
 
2
 * Copyright (C) 2000,2001,2002,2003  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
22
22
#include <stdio.h>
23
23
#include <glib.h>
24
24
 
25
 
#include "xmms/plugin.h"
26
 
#include "xmms/util.h"
 
25
#include <xmms/plugin.h>
 
26
#include <xmms/util.h>
 
27
#include <xmms/configfile.h>
 
28
#include <xmms/titlestring.h>
 
29
 
 
30
#ifdef HAVE_CONFIG_H
 
31
#include <config.h>
 
32
#endif
 
33
 
 
34
#ifdef HAVE_LANGINFO_CODESET
 
35
#include <langinfo.h>
 
36
#endif
 
37
 
27
38
#include "FLAC/all.h"
 
39
#include "plugin_common/all.h"
 
40
#include "share/grabbag.h"
 
41
#include "configure.h"
 
42
#include "wrap_id3.h"
 
43
#include "charset.h"
28
44
 
29
45
#ifdef min
30
46
#undef min
31
47
#endif
32
48
#define min(x,y) ((x)<(y)?(x):(y))
33
49
 
34
 
typedef struct {
35
 
        FLAC__byte raw[128];
36
 
        char title[31];
37
 
        char artist[31];
38
 
        char album[31];
39
 
        char comment[31];
40
 
        unsigned year;
41
 
        unsigned track; /* may be 0 if v1 (not v1.1) tag */
42
 
        unsigned genre;
43
 
        char description[1024]; /* the formatted description passed to xmms */
44
 
} id3v1_struct;
 
50
extern void FLAC_XMMS__file_info_box(char *filename);
45
51
 
46
52
typedef struct {
47
53
        FLAC__bool abort_flag;
53
59
        unsigned channels;
54
60
        unsigned sample_rate;
55
61
        unsigned length_in_msec;
 
62
        gchar *title;
56
63
        AFormat sample_format;
57
64
        int seek_to_in_sec;
 
65
        FLAC__bool has_replaygain;
 
66
        double replay_scale;
 
67
        DitherContext dither_context;
58
68
} file_info_struct;
59
69
 
60
70
static void FLAC_XMMS__init();
67
77
static void FLAC_XMMS__cleanup();
68
78
static void FLAC_XMMS__get_song_info(char *filename, char **title, int *length);
69
79
 
70
 
static FLAC__bool get_id3v1_tag_(const char *filename, id3v1_struct *tag);
71
80
static void *play_loop_(void *arg);
72
 
static FLAC__bool decoder_init_(const char *filename);
73
 
static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data);
74
 
static void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
 
81
static FLAC__bool safe_decoder_init_(const char *filename, FLAC__FileDecoder *decoder);
 
82
static void safe_decoder_finish_(FLAC__FileDecoder *decoder);
 
83
static void safe_decoder_delete_(FLAC__FileDecoder *decoder);
 
84
static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
 
85
static void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
75
86
static void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
76
87
 
77
 
 
78
88
InputPlugin flac_ip =
79
89
{
80
90
        NULL,
81
91
        NULL,
82
 
        "FLAC Player v" FLAC__VERSION_STRING,
 
92
        "Reference FLAC Player v" VERSION,
83
93
        FLAC_XMMS__init,
84
 
        NULL,
85
 
        NULL,
 
94
        FLAC_XMMS__aboutbox,
 
95
        FLAC_XMMS__configure,
86
96
        FLAC_XMMS__is_our_file,
87
97
        NULL,
88
98
        FLAC_XMMS__play_file,
99
109
        NULL,
100
110
        NULL,
101
111
        FLAC_XMMS__get_song_info,
102
 
        NULL,                   /* file_info_box */
 
112
        FLAC_XMMS__file_info_box,
103
113
        NULL
104
114
};
105
115
 
106
116
#define SAMPLES_PER_WRITE 512
107
 
static FLAC__byte reservoir_[FLAC__MAX_BLOCK_SIZE * 2 * 2 * 2]; /* *2 for max bytes-per-sample, *2 for max channels, another *2 for overflow */
108
 
static FLAC__byte output_[FLAC__MAX_BLOCK_SIZE * 2 * 2]; /* *2 for max bytes-per-sample, *2 for max channels */
109
 
static unsigned reservoir_samples_ = 0;
 
117
static FLAC__int32 reservoir_[FLAC__MAX_BLOCK_SIZE * 2/*for overflow*/ * FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS];
 
118
static FLAC__byte sample_buffer_[SAMPLES_PER_WRITE * FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS * (24/8)]; /* (24/8) for max bytes per sample */
 
119
static unsigned wide_samples_in_reservoir_ = 0;
 
120
 
110
121
static FLAC__FileDecoder *decoder_ = 0;
111
122
static file_info_struct file_info_;
112
123
static pthread_t decode_thread_;
113
124
static FLAC__bool audio_error_ = false;
114
125
 
 
126
#define BITRATE_HIST_SEGMENT_MSEC 500
 
127
/* 500ms * 50 = 25s should be enough */
 
128
#define BITRATE_HIST_SIZE 50
 
129
static unsigned bitrate_history_[BITRATE_HIST_SIZE];
 
130
 
 
131
 
115
132
InputPlugin *get_iplugin_info()
116
133
{
117
 
        flac_ip.description = g_strdup_printf("FLAC Player v%s", FLAC__VERSION_STRING);
 
134
        flac_ip.description = g_strdup_printf("Reference FLAC Player v%s", FLAC__VERSION_STRING);
118
135
        return &flac_ip;
119
136
}
120
137
 
121
138
void FLAC_XMMS__init()
122
139
{
 
140
        ConfigFile *cfg;
 
141
 
 
142
        flac_cfg.title.tag_override = FALSE;
 
143
        g_free(flac_cfg.title.tag_format);
 
144
        flac_cfg.title.convert_char_set = FALSE;
 
145
 
 
146
        cfg = xmms_cfg_open_default_file();
 
147
 
 
148
        /* title */
 
149
 
 
150
        xmms_cfg_read_boolean(cfg, "flac", "title.tag_override", &flac_cfg.title.tag_override);
 
151
 
 
152
        if(!xmms_cfg_read_string(cfg, "flac", "title.tag_format", &flac_cfg.title.tag_format))
 
153
                flac_cfg.title.tag_format = g_strdup("%p - %t");
 
154
 
 
155
        xmms_cfg_read_boolean(cfg, "flac", "title.convert_char_set", &flac_cfg.title.convert_char_set);
 
156
 
 
157
        if(!xmms_cfg_read_string(cfg, "flac", "title.file_char_set", &flac_cfg.title.file_char_set))
 
158
                flac_cfg.title.file_char_set = FLAC_plugin__charset_get_current();
 
159
 
 
160
        if(!xmms_cfg_read_string(cfg, "flac", "title.user_char_set", &flac_cfg.title.user_char_set))
 
161
                flac_cfg.title.user_char_set = FLAC_plugin__charset_get_current();
 
162
 
 
163
        /* replaygain */
 
164
 
 
165
        xmms_cfg_read_boolean(cfg, "flac", "output.replaygain.enable", &flac_cfg.output.replaygain.enable);
 
166
 
 
167
        xmms_cfg_read_boolean(cfg, "flac", "output.replaygain.album_mode", &flac_cfg.output.replaygain.album_mode);
 
168
 
 
169
        if(!xmms_cfg_read_int(cfg, "flac", "output.replaygain.preamp", &flac_cfg.output.replaygain.preamp))
 
170
                flac_cfg.output.replaygain.preamp = 0;
 
171
 
 
172
        xmms_cfg_read_boolean(cfg, "flac", "output.replaygain.hard_limit", &flac_cfg.output.replaygain.hard_limit);
 
173
 
 
174
        xmms_cfg_read_boolean(cfg, "flac", "output.resolution.normal.dither_24_to_16", &flac_cfg.output.resolution.normal.dither_24_to_16);
 
175
        xmms_cfg_read_boolean(cfg, "flac", "output.resolution.replaygain.dither", &flac_cfg.output.resolution.replaygain.dither);
 
176
 
 
177
        if(!xmms_cfg_read_int(cfg, "flac", "output.resolution.replaygain.noise_shaping", &flac_cfg.output.resolution.replaygain.noise_shaping))
 
178
                flac_cfg.output.resolution.replaygain.noise_shaping = 1;
 
179
 
 
180
        if(!xmms_cfg_read_int(cfg, "flac", "output.resolution.replaygain.bps_out", &flac_cfg.output.resolution.replaygain.bps_out))
 
181
                flac_cfg.output.resolution.replaygain.bps_out = 16;
 
182
 
123
183
        decoder_ = FLAC__file_decoder_new();
124
184
}
125
185
 
137
197
void FLAC_XMMS__play_file(char *filename)
138
198
{
139
199
        FILE *f;
140
 
        id3v1_struct tag;
141
200
 
142
 
        reservoir_samples_ = 0;
 
201
        wide_samples_in_reservoir_ = 0;
143
202
        audio_error_ = false;
144
203
        file_info_.abort_flag = false;
145
204
        file_info_.is_playing = false;
146
205
        file_info_.eof = false;
147
206
        file_info_.play_thread_open = false;
 
207
        file_info_.has_replaygain = false;
148
208
 
149
209
        if(0 == (f = fopen(filename, "r")))
150
210
                return;
151
211
        fclose(f);
152
212
 
153
 
        if(!decoder_init_(filename))
154
 
                return;
 
213
        if(decoder_ == 0)
 
214
                return;
 
215
 
 
216
        if(!safe_decoder_init_(filename, decoder_))
 
217
                return;
 
218
 
 
219
        if(file_info_.has_replaygain && flac_cfg.output.replaygain.enable && flac_cfg.output.resolution.replaygain.dither)
 
220
                FLAC__plugin_common__init_dither_context(&file_info_.dither_context, file_info_.bits_per_sample, flac_cfg.output.resolution.replaygain.noise_shaping);
155
221
 
156
222
        file_info_.is_playing = true;
157
223
 
158
224
        if(flac_ip.output->open_audio(file_info_.sample_format, file_info_.sample_rate, file_info_.channels) == 0) {
159
225
                audio_error_ = true;
160
 
                if(decoder_)
161
 
                        FLAC__file_decoder_finish(decoder_);
 
226
                safe_decoder_finish_(decoder_);
162
227
                return;
163
228
        }
164
229
 
165
 
        (void)get_id3v1_tag_(filename, &tag);
166
 
        flac_ip.set_info(tag.description, file_info_.length_in_msec, file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample, file_info_.sample_rate, file_info_.channels);
 
230
        file_info_.title = flac_format_song_title(filename);
 
231
        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);
167
232
 
168
233
        file_info_.seek_to_in_sec = -1;
169
234
        file_info_.play_thread_open = true;
179
244
                        pthread_join(decode_thread_, NULL);
180
245
                }
181
246
                flac_ip.output->close_audio();
182
 
                if(decoder_)
183
 
                        FLAC__file_decoder_finish(decoder_);
 
247
                safe_decoder_finish_(decoder_);
184
248
        }
185
249
}
186
250
 
210
274
 
211
275
void FLAC_XMMS__cleanup()
212
276
{
213
 
        if(decoder_) {
214
 
                FLAC__file_decoder_delete(decoder_);
215
 
                decoder_ = 0;
216
 
        }
 
277
        safe_decoder_delete_(decoder_);
 
278
        decoder_ = 0;
217
279
}
218
280
 
219
281
void FLAC_XMMS__get_song_info(char *filename, char **title, int *length_in_msec)
220
282
{
221
 
        id3v1_struct tag;
 
283
        FLAC__StreamMetadata streaminfo;
 
284
 
 
285
        if(0 == filename)
 
286
                filename = "";
 
287
 
 
288
        if(!FLAC__metadata_get_streaminfo(filename, &streaminfo)) {
 
289
                /* @@@ how to report the error? */
 
290
                if(title) {
 
291
                        static const char *errtitle = "Invalid FLAC File: ";
 
292
                        *title = g_malloc(strlen(errtitle) + 1 + strlen(filename) + 1 + 1);
 
293
                        sprintf(*title, "%s\"%s\"", errtitle, filename);
 
294
                }
 
295
                if(length_in_msec)
 
296
                        *length_in_msec = -1;
 
297
                return;
 
298
        }
222
299
 
223
300
        if(title) {
224
 
                (void)get_id3v1_tag_(filename, &tag);
225
 
                *title = g_malloc(strlen(tag.description)+1);
226
 
                strcpy(*title, tag.description);
227
 
        }
228
 
        if(length_in_msec) {
229
 
                FLAC__FileDecoder *tmp_decoder = FLAC__file_decoder_new();
230
 
                file_info_struct tmp_file_info;
231
 
                if(0 == tmp_decoder) {
232
 
                        *length_in_msec = -1;
233
 
                        return;
234
 
                }
235
 
                tmp_file_info.abort_flag = false;
236
 
                FLAC__file_decoder_set_md5_checking(tmp_decoder, false);
237
 
                FLAC__file_decoder_set_filename(tmp_decoder, filename);
238
 
                FLAC__file_decoder_set_write_callback(tmp_decoder, write_callback_);
239
 
                FLAC__file_decoder_set_metadata_callback(tmp_decoder, metadata_callback_);
240
 
                FLAC__file_decoder_set_error_callback(tmp_decoder, error_callback_);
241
 
                FLAC__file_decoder_set_client_data(tmp_decoder, &tmp_file_info);
242
 
                if(FLAC__file_decoder_init(tmp_decoder) != FLAC__FILE_DECODER_OK) {
243
 
                        *length_in_msec = -1;
244
 
                        return;
245
 
                }
246
 
                if(!FLAC__file_decoder_process_metadata(tmp_decoder)) {
247
 
                        *length_in_msec = -1;
248
 
                        return;
249
 
                }
250
 
 
251
 
                *length_in_msec = (int)tmp_file_info.length_in_msec;
252
 
 
253
 
                FLAC__file_decoder_finish(tmp_decoder);
254
 
                FLAC__file_decoder_delete(tmp_decoder);
255
 
        }
 
301
                *title = flac_format_song_title(filename);
 
302
        }
 
303
        if(length_in_msec)
 
304
                *length_in_msec = streaminfo.data.stream_info.total_samples * 10 / (streaminfo.data.stream_info.sample_rate / 100);
256
305
}
257
306
 
258
307
/***********************************************************************
259
308
 * local routines
260
309
 **********************************************************************/
261
310
 
262
 
FLAC__bool get_id3v1_tag_(const char *filename, id3v1_struct *tag)
263
 
{
264
 
        const char *temp;
265
 
        FILE *f = fopen(filename, "rb");
266
 
        memset(tag, 0, sizeof(id3v1_struct));
267
 
 
268
 
        /* set the title and description to the filename by default */
269
 
        temp = strrchr(filename, '/');
270
 
        if(!temp)
271
 
                temp = filename;
272
 
        else
273
 
                temp++;
274
 
        strcpy(tag->description, temp);
275
 
        *strrchr(tag->description, '.') = '\0';
276
 
        strncpy(tag->title, tag->description, 30); tag->title[30] = '\0';
277
 
 
278
 
        if(0 == f)
279
 
                return false;
280
 
        if(-1 == fseek(f, -128, SEEK_END)) {
281
 
                fclose(f);
282
 
                return false;
283
 
        }
284
 
        if(fread(tag->raw, 1, 128, f) < 128) {
285
 
                fclose(f);
286
 
                return false;
287
 
        }
288
 
        fclose(f);
289
 
        if(strncmp(tag->raw, "TAG", 3))
290
 
                return false;
291
 
        else {
292
 
                char year_str[5];
293
 
 
294
 
                memcpy(tag->title, tag->raw+3, 30);
295
 
                memcpy(tag->artist, tag->raw+33, 30);
296
 
                memcpy(tag->album, tag->raw+63, 30);
297
 
                memcpy(year_str, tag->raw+93, 4); year_str[4] = '\0'; tag->year = atoi(year_str);
298
 
                memcpy(tag->comment, tag->raw+97, 30);
299
 
                tag->genre = (unsigned)((FLAC__byte)tag->raw[127]);
300
 
                tag->track = (unsigned)((FLAC__byte)tag->raw[126]);
301
 
 
302
 
                sprintf(tag->description, "%s - %s", tag->artist, tag->title);
303
 
 
304
 
                return true;
305
 
        }
306
 
}
307
 
 
308
311
void *play_loop_(void *arg)
309
312
{
 
313
        unsigned written_time_last = 0, bh_index_last_w = 0, bh_index_last_o = BITRATE_HIST_SIZE, blocksize = 1;
 
314
        FLAC__uint64 decode_position_last = 0, decode_position_frame_last = 0, decode_position_frame = 0;
 
315
 
310
316
        (void)arg;
311
317
 
312
318
        while(file_info_.is_playing) {
313
319
                if(!file_info_.eof) {
314
 
                        while(reservoir_samples_ < SAMPLES_PER_WRITE) {
 
320
                        while(wide_samples_in_reservoir_ < SAMPLES_PER_WRITE) {
 
321
                                unsigned s;
 
322
 
 
323
                                s = wide_samples_in_reservoir_;
315
324
                                if(FLAC__file_decoder_get_state(decoder_) == FLAC__FILE_DECODER_END_OF_FILE) {
316
325
                                        file_info_.eof = true;
317
326
                                        break;
318
327
                                }
319
 
                                else if(!FLAC__file_decoder_process_one_frame(decoder_))
 
328
                                else if(!FLAC__file_decoder_process_single(decoder_)) {
 
329
                                        /*@@@ this should probably be a dialog */
 
330
                                        fprintf(stderr, "libxmms-flac: READ ERROR processing frame\n");
 
331
                                        file_info_.eof = true;
320
332
                                        break;
 
333
                                }
 
334
                                blocksize = wide_samples_in_reservoir_ - s;
 
335
                                decode_position_frame_last = decode_position_frame;
 
336
                                if(!FLAC__file_decoder_get_decode_position(decoder_, &decode_position_frame))
 
337
                                        decode_position_frame = 0;
321
338
                        }
322
 
                        if(reservoir_samples_ > 0) {
 
339
                        if(wide_samples_in_reservoir_ > 0) {
323
340
                                const unsigned channels = file_info_.channels;
324
 
                                const unsigned bytes_per_sample = (file_info_.bits_per_sample+7)/8;
325
 
                                unsigned i, n = min(reservoir_samples_, SAMPLES_PER_WRITE), delta;
326
 
                                unsigned bytes = n * bytes_per_sample * channels;
327
 
 
328
 
                                for(i = 0; i < bytes; i++)
329
 
                                        output_[i] = reservoir_[i];
330
 
                                delta = i;
331
 
                                for( ; i < reservoir_samples_*bytes_per_sample*channels; i++)
 
341
                                const unsigned bits_per_sample = file_info_.bits_per_sample;
 
342
                                const unsigned n = min(wide_samples_in_reservoir_, SAMPLES_PER_WRITE);
 
343
                                const unsigned delta = n * channels;
 
344
                                int bytes;
 
345
                                unsigned i, written_time, bh_index_w;
 
346
                                FLAC__uint64 decode_position;
 
347
 
 
348
                                if(flac_cfg.output.replaygain.enable && file_info_.has_replaygain) {
 
349
                                        bytes = (int)FLAC__plugin_common__apply_gain(
 
350
                                                sample_buffer_,
 
351
                                                reservoir_,
 
352
                                                n,
 
353
                                                channels,
 
354
                                                bits_per_sample,
 
355
                                                flac_cfg.output.resolution.replaygain.bps_out,
 
356
                                                file_info_.replay_scale,
 
357
                                                flac_cfg.output.replaygain.hard_limit,
 
358
                                                flac_cfg.output.resolution.replaygain.dither,
 
359
                                                (NoiseShaping)flac_cfg.output.resolution.replaygain.noise_shaping,
 
360
                                                &file_info_.dither_context
 
361
                                        );
 
362
                                }
 
363
                                else {
 
364
                                        bytes = (int)FLAC__plugin_common__pack_pcm_signed_little_endian(
 
365
                                                sample_buffer_,
 
366
                                                reservoir_,
 
367
                                                n,
 
368
                                                channels,
 
369
                                                bits_per_sample,
 
370
                                                flac_cfg.output.resolution.normal.dither_24_to_16?
 
371
                                                        min(bits_per_sample, 16) :
 
372
                                                        bits_per_sample
 
373
                                        );
 
374
                                }
 
375
 
 
376
                                for(i = delta; i < wide_samples_in_reservoir_ * channels; i++)
332
377
                                        reservoir_[i-delta] = reservoir_[i];
333
 
                                reservoir_samples_ -= n;
 
378
                                wide_samples_in_reservoir_ -= n;
334
379
 
335
 
                                flac_ip.add_vis_pcm(flac_ip.output->written_time(), file_info_.sample_format, channels, bytes, output_);
 
380
                                flac_ip.add_vis_pcm(flac_ip.output->written_time(), file_info_.sample_format, channels, bytes, sample_buffer_);
336
381
                                while(flac_ip.output->buffer_free() < (int)bytes && file_info_.is_playing && file_info_.seek_to_in_sec == -1)
337
382
                                        xmms_usleep(10000);
338
383
                                if(file_info_.is_playing && file_info_.seek_to_in_sec == -1)
339
 
                                        flac_ip.output->write_audio(output_, bytes);
 
384
                                        flac_ip.output->write_audio(sample_buffer_, bytes);
 
385
 
 
386
                                /* compute current bitrate */
 
387
 
 
388
                                written_time = flac_ip.output->written_time();
 
389
                                bh_index_w = written_time / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
 
390
                                if(bh_index_w != bh_index_last_w) {
 
391
                                        bh_index_last_w = bh_index_w;
 
392
                                        decode_position = decode_position_frame - (double)wide_samples_in_reservoir_ * (double)(decode_position_frame - decode_position_frame_last) / (double)blocksize;
 
393
                                        bitrate_history_[(bh_index_w + BITRATE_HIST_SIZE - 1) % BITRATE_HIST_SIZE] =
 
394
                                                decode_position > decode_position_last && written_time > written_time_last ?
 
395
                                                        8000 * (decode_position - decode_position_last) / (written_time - written_time_last) :
 
396
                                                        file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample;
 
397
                                        decode_position_last = decode_position;
 
398
                                        written_time_last = written_time;
 
399
                                }
340
400
                        }
341
401
                        else {
342
402
                                file_info_.eof = true;
350
410
                        unsigned target_sample = (unsigned)(distance * (double)file_info_.total_samples);
351
411
                        if(FLAC__file_decoder_seek_absolute(decoder_, (FLAC__uint64)target_sample)) {
352
412
                                flac_ip.output->flush(file_info_.seek_to_in_sec * 1000);
 
413
                                bh_index_last_w = bh_index_last_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
 
414
                                if(!FLAC__file_decoder_get_decode_position(decoder_, &decode_position_frame))
 
415
                                        decode_position_frame = 0;
353
416
                                file_info_.seek_to_in_sec = -1;
354
417
                                file_info_.eof = false;
355
 
                                reservoir_samples_ = 0;
 
418
                                wide_samples_in_reservoir_ = 0;
 
419
                        }
 
420
                }
 
421
                else {
 
422
                        /* display the right bitrate from history */
 
423
                        unsigned bh_index_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
 
424
                        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) {
 
425
                                bh_index_last_o = bh_index_o;
 
426
                                flac_ip.set_info(file_info_.title, file_info_.length_in_msec, bitrate_history_[bh_index_o], file_info_.sample_rate, file_info_.channels);
356
427
                        }
357
428
                }
358
429
        }
359
430
 
360
 
        if(decoder_)
361
 
                FLAC__file_decoder_finish(decoder_);
 
431
        safe_decoder_finish_(decoder_);
362
432
 
363
433
        /* are these two calls necessary? */
364
434
        flac_ip.output->buffer_free();
365
435
        flac_ip.output->buffer_free();
366
436
 
 
437
        g_free(file_info_.title);
 
438
 
367
439
        pthread_exit(NULL);
368
440
        return 0; /* to silence the compiler warning about not returning a value */
369
441
}
370
442
 
371
 
FLAC__bool decoder_init_(const char *filename)
 
443
FLAC__bool safe_decoder_init_(const char *filename, FLAC__FileDecoder *decoder)
372
444
{
373
 
        if(decoder_ == 0)
374
 
                return false;
375
 
 
376
 
        FLAC__file_decoder_set_md5_checking(decoder_, false);
377
 
        FLAC__file_decoder_set_filename(decoder_, filename);
378
 
        FLAC__file_decoder_set_write_callback(decoder_, write_callback_);
379
 
        FLAC__file_decoder_set_metadata_callback(decoder_, metadata_callback_);
380
 
        FLAC__file_decoder_set_error_callback(decoder_, error_callback_);
381
 
        FLAC__file_decoder_set_client_data(decoder_, &file_info_);
382
 
        if(FLAC__file_decoder_init(decoder_) != FLAC__FILE_DECODER_OK)
383
 
                return false;
384
 
 
385
 
        if(!FLAC__file_decoder_process_metadata(decoder_))
 
445
        if(decoder == 0)
 
446
                return false;
 
447
 
 
448
        safe_decoder_finish_(decoder);
 
449
 
 
450
        FLAC__file_decoder_set_md5_checking(decoder, false);
 
451
        FLAC__file_decoder_set_filename(decoder, filename);
 
452
        FLAC__file_decoder_set_metadata_ignore_all(decoder);
 
453
        FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
 
454
        FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
 
455
        FLAC__file_decoder_set_write_callback(decoder, write_callback_);
 
456
        FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback_);
 
457
        FLAC__file_decoder_set_error_callback(decoder, error_callback_);
 
458
        FLAC__file_decoder_set_client_data(decoder, &file_info_);
 
459
        if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK)
 
460
                return false;
 
461
 
 
462
        if(!FLAC__file_decoder_process_until_end_of_metadata(decoder))
386
463
                return false;
387
464
 
388
465
        return true;
389
466
}
390
467
 
391
 
FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data)
 
468
void safe_decoder_finish_(FLAC__FileDecoder *decoder)
 
469
{
 
470
        if(decoder && FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_UNINITIALIZED)
 
471
                FLAC__file_decoder_finish(decoder);
 
472
}
 
473
 
 
474
void safe_decoder_delete_(FLAC__FileDecoder *decoder)
 
475
{
 
476
        if(decoder) {
 
477
                safe_decoder_finish_(decoder);
 
478
                FLAC__file_decoder_delete(decoder);
 
479
        }
 
480
}
 
481
 
 
482
FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
392
483
{
393
484
        file_info_struct *file_info = (file_info_struct *)client_data;
394
 
        const unsigned bps = file_info->bits_per_sample, channels = file_info->channels, wide_samples = frame->header.blocksize;
395
 
        unsigned wide_sample, sample, channel;
396
 
        FLAC__int8 *scbuffer = (FLAC__int8*)reservoir_;
397
 
        FLAC__int16 *ssbuffer = (FLAC__int16*)reservoir_;
 
485
        const unsigned channels = file_info->channels, wide_samples = frame->header.blocksize;
 
486
        unsigned wide_sample, offset_sample, channel;
398
487
 
399
488
        (void)decoder;
400
489
 
401
490
        if(file_info->abort_flag)
402
 
                return FLAC__STREAM_DECODER_WRITE_ABORT;
403
 
 
404
 
        if(bps == 8) {
405
 
                for(sample = reservoir_samples_*channels, wide_sample = 0; wide_sample < wide_samples; wide_sample++)
406
 
                        for(channel = 0; channel < channels; channel++, sample++)
407
 
                                scbuffer[sample] = (FLAC__int8)buffer[channel][wide_sample];
408
 
        }
409
 
        else if(bps == 16) {
410
 
                for(sample = reservoir_samples_*channels, wide_sample = 0; wide_sample < wide_samples; wide_sample++)
411
 
                        for(channel = 0; channel < channels; channel++, sample++)
412
 
                                ssbuffer[sample] = (FLAC__int16)buffer[channel][wide_sample];
413
 
        }
414
 
        else {
415
 
                file_info->abort_flag = true;
416
 
                return FLAC__STREAM_DECODER_WRITE_ABORT;
417
 
        }
418
 
 
419
 
        reservoir_samples_ += wide_samples;
420
 
 
421
 
        return FLAC__STREAM_DECODER_WRITE_CONTINUE;
 
491
                return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
 
492
 
 
493
        for(offset_sample = wide_samples_in_reservoir_ * channels, wide_sample = 0; wide_sample < wide_samples; wide_sample++)
 
494
                for(channel = 0; channel < channels; channel++, offset_sample++)
 
495
                        reservoir_[offset_sample] = buffer[channel][wide_sample];
 
496
 
 
497
        wide_samples_in_reservoir_ += wide_samples;
 
498
 
 
499
        return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
422
500
}
423
501
 
424
 
void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)
 
502
void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
425
503
{
426
504
        file_info_struct *file_info = (file_info_struct *)client_data;
427
505
        (void)decoder;
432
510
                file_info->channels = metadata->data.stream_info.channels;
433
511
                file_info->sample_rate = metadata->data.stream_info.sample_rate;
434
512
 
 
513
#ifdef FLAC__DO_DITHER
 
514
                if(file_info->bits_per_sample == 8) {
 
515
                        file_info->sample_format = FMT_S8;
 
516
                }
 
517
                else if(file_info->bits_per_sample == 16 || file_info->bits_per_sample == 24) {
 
518
                        file_info->sample_format = FMT_S16_LE;
 
519
                }
 
520
                else {
 
521
                        /*@@@ need some error here like wa2: MessageBox(mod_.hMainWindow, "ERROR: plugin can only handle 8/16/24-bit samples\n", "ERROR: plugin can only handle 8/16/24-bit samples", 0); */
 
522
                        file_info->abort_flag = true;
 
523
                        return;
 
524
                }
 
525
#else
435
526
                if(file_info->bits_per_sample == 8) {
436
527
                        file_info->sample_format = FMT_S8;
437
528
                }
438
529
                else if(file_info->bits_per_sample == 16) {
439
 
                        file_info->sample_format = FMT_S16_NE;
 
530
                        file_info->sample_format = FMT_S16_LE;
440
531
                }
441
532
                else {
 
533
                        /*@@@ 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); */
442
534
                        file_info->abort_flag = true;
443
535
                        return;
444
536
                }
 
537
#endif
445
538
                file_info->length_in_msec = file_info->total_samples * 10 / (file_info->sample_rate / 100);
446
539
        }
 
540
        else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
 
541
                double gain, peak;
 
542
                if(grabbag__replaygain_load_from_vorbiscomment(metadata, flac_cfg.output.replaygain.album_mode, &gain, &peak)) {
 
543
                        file_info_.has_replaygain = true;
 
544
                        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);
 
545
                }
 
546
        }
447
547
}
448
548
 
449
549
void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
450
550
{
451
551
        file_info_struct *file_info = (file_info_struct *)client_data;
452
552
        (void)decoder;
453
 
        if(status != FLAC__STREAM_DECODER_ERROR_LOST_SYNC)
 
553
        if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC)
454
554
                file_info->abort_flag = true;
455
555
}