comparison src/flac/plugin.c @ 96:63bde7ca7ad0 trunk

[svn] First attempt at porting our FLAC plugin to API 1.1.3 (completely incompatible, as usual!). Needs more work and a version-sensitize FLAC checker.
author chainsaw
date Sat, 21 Oct 2006 09:21:12 -0700
parents 3da1b8942b8b
children a19f24790f3c
comparison
equal deleted inserted replaced
95:b5a1b762f586 96:63bde7ca7ad0
1 /* libxmms-flac - XMMS FLAC input plugin 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 Josh Coalson
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2 6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version. 7 * of the License, or (at your option) any later version.
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */ 17 */
18 18
19 #include <limits.h>
19 #include <stdlib.h> 20 #include <stdlib.h>
20 #include <string.h> 21 #include <string.h>
21 #include <stdio.h> 22 #include <stdio.h>
22 #include <glib.h> 23 #include <glib.h>
23 #include <pwd.h> 24 #include <pwd.h>
51 #ifdef min 52 #ifdef min
52 #undef min 53 #undef min
53 #endif 54 #endif
54 #define min(x,y) ((x)<(y)?(x):(y)) 55 #define min(x,y) ((x)<(y)?(x):(y))
55 56
56 /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
57 #ifdef _MSC_VER
58 #define FLAC__U64L(x) x
59 #else
60 #define FLAC__U64L(x) x##LLU
61 #endif
62
63 extern void FLAC_XMMS__file_info_box(char *filename); 57 extern void FLAC_XMMS__file_info_box(char *filename);
64 58
65 typedef struct { 59 typedef struct {
66 FLAC__bool abort_flag; 60 FLAC__bool abort_flag;
67 FLAC__bool is_playing; 61 FLAC__bool is_playing;
62 FLAC__bool is_http_source;
68 FLAC__bool eof; 63 FLAC__bool eof;
69 FLAC__bool play_thread_open; /* if true, is_playing must also be true */ 64 FLAC__bool play_thread_open; /* if true, is_playing must also be true */
70 unsigned total_samples; 65 FLAC__uint64 total_samples;
71 unsigned bits_per_sample; 66 unsigned bits_per_sample;
72 unsigned channels; 67 unsigned channels;
73 unsigned sample_rate; 68 unsigned sample_rate;
74 unsigned length_in_msec; 69 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 */
75 gchar *title; 70 gchar *title;
76 AFormat sample_format; 71 AFormat sample_format;
77 unsigned sample_format_bytes_per_sample; 72 unsigned sample_format_bytes_per_sample;
78 int seek_to_in_sec; 73 int seek_to_in_sec;
79 FLAC__bool has_replaygain; 74 FLAC__bool has_replaygain;
80 double replay_scale; 75 double replay_scale;
81 DitherContext dither_context; 76 DitherContext dither_context;
82 } file_info_struct; 77 } stream_data_struct;
83
84 typedef FLAC__StreamDecoderWriteStatus (*WriteCallback) (const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
85 typedef void (*MetadataCallback) (const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
86 typedef void (*ErrorCallback) (const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
87
88 typedef struct {
89 FLAC__bool seekable;
90 void* (*new_decoder) (void);
91 FLAC__bool (*set_md5_checking) (void *decoder, FLAC__bool value);
92 FLAC__bool (*set_source) (void *decoder, const char* source);
93 FLAC__bool (*set_metadata_ignore_all) (void *decoder);
94 FLAC__bool (*set_metadata_respond) (void *decoder, FLAC__MetadataType type);
95 FLAC__bool (*set_write_callback) (void *decoder, WriteCallback value);
96 FLAC__bool (*set_metadata_callback) (void *decoder, MetadataCallback value);
97 FLAC__bool (*set_error_callback) (void *decoder, ErrorCallback value);
98 FLAC__bool (*set_client_data) (void *decoder, void *value);
99 FLAC__bool (*decoder_init) (void *decoder);
100 void (*safe_decoder_finish) (void *decoder);
101 void (*safe_decoder_delete) (void *decoder);
102 FLAC__bool (*process_until_end_of_metadata) (void *decoder);
103 FLAC__bool (*process_single) (void *decoder);
104 FLAC__bool (*is_eof) (void *decoder);
105 } decoder_funcs_t;
106
107 #define NUM_DECODER_TYPES 2
108 typedef enum {
109 DECODER_FILE,
110 DECODER_HTTP
111 } decoder_t;
112 78
113 static void FLAC_XMMS__init(); 79 static void FLAC_XMMS__init();
114 static int FLAC_XMMS__is_our_file(char *filename); 80 static int FLAC_XMMS__is_our_file(char *filename);
115 static void FLAC_XMMS__play_file(char *filename); 81 static void FLAC_XMMS__play_file(char *filename);
116 static void FLAC_XMMS__stop(); 82 static void FLAC_XMMS__stop();
120 static void FLAC_XMMS__cleanup(); 86 static void FLAC_XMMS__cleanup();
121 static void FLAC_XMMS__get_song_info(char *filename, char **title, int *length); 87 static void FLAC_XMMS__get_song_info(char *filename, char **title, int *length);
122 88
123 static void *play_loop_(void *arg); 89 static void *play_loop_(void *arg);
124 90
125 static FLAC__bool safe_decoder_init_(const char *filename, void **decoderp, decoder_funcs_t const ** fnsp); 91 static FLAC__bool safe_decoder_init_(const char *filename, FLAC__StreamDecoder *decoder);
126 static void file_decoder_safe_decoder_finish_(void *decoder); 92 static void safe_decoder_finish_(FLAC__StreamDecoder *decoder);
127 static void file_decoder_safe_decoder_delete_(void *decoder); 93 static void safe_decoder_delete_(FLAC__StreamDecoder *decoder);
128 static FLAC__StreamDecoderWriteStatus write_callback_(const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); 94
129 static void metadata_callback_(const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data); 95 static FLAC__StreamDecoderReadStatus http_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
130 static void error_callback_(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); 96 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
131 97 static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
132 static void init_decoder_func_tables(); 98 static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
133 static decoder_t source_to_decoder_type (const char *source);
134 99
135 InputPlugin flac_ip = 100 InputPlugin flac_ip =
136 { 101 {
137 NULL, 102 NULL,
138 NULL, 103 NULL,
164 #define SAMPLES_PER_WRITE 512 129 #define SAMPLES_PER_WRITE 512
165 #define SAMPLE_BUFFER_SIZE ((FLAC__MAX_BLOCK_SIZE + SAMPLES_PER_WRITE) * FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS * (24/8)) 130 #define SAMPLE_BUFFER_SIZE ((FLAC__MAX_BLOCK_SIZE + SAMPLES_PER_WRITE) * FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS * (24/8))
166 static FLAC__byte sample_buffer_[SAMPLE_BUFFER_SIZE]; 131 static FLAC__byte sample_buffer_[SAMPLE_BUFFER_SIZE];
167 static unsigned sample_buffer_first_, sample_buffer_last_; 132 static unsigned sample_buffer_first_, sample_buffer_last_;
168 133
169 static void *decoder_ = 0, *decoder2 = 0; 134 static FLAC__StreamDecoder *decoder_ = 0, *decoder2 = 0;
170 static file_info_struct file_info_; 135 static stream_data_struct stream_data_;
171 static GThread *decode_thread_; 136 static GThread *decode_thread_;
172 static FLAC__bool audio_error_ = false; 137 static FLAC__bool audio_error_ = false;
173 static FLAC__bool is_big_endian_host_; 138 static FLAC__bool is_big_endian_host_;
174 139
175 #define BITRATE_HIST_SEGMENT_MSEC 500 140 #define BITRATE_HIST_SEGMENT_MSEC 500
176 /* 500ms * 50 = 25s should be enough */ 141 /* 500ms * 50 = 25s should be enough */
177 #define BITRATE_HIST_SIZE 50 142 #define BITRATE_HIST_SIZE 50
178 static unsigned bitrate_history_[BITRATE_HIST_SIZE]; 143 static unsigned bitrate_history_[BITRATE_HIST_SIZE];
179 144
180 /* A table of sets of decoder functions, indexed by decoder_t */ 145 #ifdef SUPPORT_ATTRIBUTE_VISIBILITY
181 static const decoder_funcs_t* DECODER_FUNCS[NUM_DECODER_TYPES]; 146 InputPlugin *get_iplugin_info() __attribute__((visibility("default")));
182 147 #endif
183 static decoder_funcs_t const * decoder_func_table_, * decoder_func_table2;
184
185 148
186 InputPlugin *get_iplugin_info() 149 InputPlugin *get_iplugin_info()
187 { 150 {
188 flac_ip.description = g_strdup_printf(_("FLAC Audio Plugin")); 151 flac_ip.description = g_strdup_printf(_("FLAC Audio Plugin"));
189 return &flac_ip; 152 return &flac_ip;
190 } 153 }
191 154
192 void set_track_info(const char* title, int length_in_msec) 155 void set_track_info(const char* title, int length_in_msec)
193 { 156 {
194 if (file_info_.is_playing) { 157 if (stream_data_.is_playing) {
195 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); 158 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);
196 } 159 }
197 } 160 }
198 161
199 static gchar* homedir() 162 static gchar* homedir()
200 { 163 {
212 endpwent(); 175 endpwent();
213 } 176 }
214 return result; 177 return result;
215 } 178 }
216 179
180 static FLAC__bool is_http_source(const char *source)
181 {
182 return 0 == strncasecmp(source, "http://", 7);
183 }
184
217 void FLAC_XMMS__init() 185 void FLAC_XMMS__init()
218 { 186 {
219 ConfigDb *db; 187 ConfigDb *db;
220 FLAC__uint32 test = 1; 188 FLAC__uint32 test = 1;
221 gchar *tmp = NULL;
222 189
223 is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true; 190 is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
224 191
225 memset(&flac_cfg, 0, sizeof(flac_cfg)); 192 flac_cfg.title.tag_override = FALSE;
193 if (flac_cfg.title.tag_format)
194 g_free(flac_cfg.title.tag_format);
195 flac_cfg.title.convert_char_set = FALSE;
226 196
227 db = bmp_cfg_db_open(); 197 db = bmp_cfg_db_open();
228 198
229 /* title */ 199 /* title */
230 200
273 flac_cfg.stream.save_http_path = homedir(); 243 flac_cfg.stream.save_http_path = homedir();
274 } 244 }
275 bmp_cfg_db_get_bool(db, "flac", "stream.cast_title_streaming", &flac_cfg.stream.cast_title_streaming); 245 bmp_cfg_db_get_bool(db, "flac", "stream.cast_title_streaming", &flac_cfg.stream.cast_title_streaming);
276 bmp_cfg_db_get_bool(db, "flac", "stream.use_udp_channel", &flac_cfg.stream.use_udp_channel); 246 bmp_cfg_db_get_bool(db, "flac", "stream.use_udp_channel", &flac_cfg.stream.use_udp_channel);
277 247
278 init_decoder_func_tables();
279 decoder_func_table_ = DECODER_FUNCS [DECODER_FILE];
280 decoder_ = decoder_func_table_ -> new_decoder();
281
282 bmp_cfg_db_get_bool(db, NULL, "use_proxy", &flac_cfg.stream.use_proxy); 248 bmp_cfg_db_get_bool(db, NULL, "use_proxy", &flac_cfg.stream.use_proxy);
283 bmp_cfg_db_get_string(db, NULL, "proxy_host", &flac_cfg.stream.proxy_host); 249 bmp_cfg_db_get_string(db, NULL, "proxy_host", &flac_cfg.stream.proxy_host);
284 bmp_cfg_db_get_string(db, NULL, "proxy_port", &tmp); 250 bmp_cfg_db_get_string(db, NULL, "proxy_port", &tmp);
285 251
286 if (tmp != NULL)
287 flac_cfg.stream.proxy_port = atoi(tmp);
288
289 bmp_cfg_db_get_bool(db, NULL, "proxy_use_auth", &flac_cfg.stream.proxy_use_auth); 252 bmp_cfg_db_get_bool(db, NULL, "proxy_use_auth", &flac_cfg.stream.proxy_use_auth);
290 bmp_cfg_db_get_string(db, NULL, "proxy_user", &flac_cfg.stream.proxy_user); 253 bmp_cfg_db_get_string(db, NULL, "proxy_user", &flac_cfg.stream.proxy_user);
291 bmp_cfg_db_get_string(db, NULL, "proxy_pass", &flac_cfg.stream.proxy_pass); 254 bmp_cfg_db_get_string(db, NULL, "proxy_pass", &flac_cfg.stream.proxy_pass);
292 255
256 decoder_ = FLAC__stream_decoder_new();
293 bmp_cfg_db_close(db); 257 bmp_cfg_db_close(db);
294 } 258 }
295 259
296 int FLAC_XMMS__is_our_file(char *filename) 260 int FLAC_XMMS__is_our_file(char *filename)
297 { 261 {
298 FILE *f; 262 FILE *f;
299 FLAC__StreamMetadata streaminfo; 263 FLAC__StreamMetadata streaminfo;
300 264
301 if (source_to_decoder_type (filename) == DECODER_FILE) { 265 if(!is_http_source(filename)) {
302 if(0 == (f = fopen(filename, "r"))) 266 if(0 == (f = fopen(filename, "r")))
303 return 0;
304 fclose(f);
305 if(!FLAC__metadata_get_streaminfo(filename, &streaminfo))
306 return 0; 267 return 0;
307 return 1; 268 fclose(f);
308 } 269 if(FLAC__metadata_get_streaminfo(filename, &streaminfo))
309 270 return 1;
310 if(!safe_decoder_init_(filename, &decoder2, &decoder_func_table2))
311 return 0; 271 return 0;
312 272 }
313 decoder_func_table2 -> safe_decoder_finish(decoder2); 273
274 if(!safe_decoder_init_(filename, decoder2))
275 return 0;
276
277 safe_decoder_finish_(decoder2);
314 return 1; 278 return 1;
315 } 279 }
316 280
317 void FLAC_XMMS__play_file(char *filename) 281 void FLAC_XMMS__play_file(char *filename)
318 { 282 {
319 FILE *f; 283 FILE *f;
320 284
321 sample_buffer_first_ = sample_buffer_last_ = 0; 285 sample_buffer_first_ = sample_buffer_last_ = 0;
322 audio_error_ = false; 286 audio_error_ = false;
323 file_info_.abort_flag = false; 287 stream_data_.abort_flag = false;
324 file_info_.is_playing = false; 288 stream_data_.is_playing = false;
325 file_info_.eof = false; 289 stream_data_.is_http_source = is_http_source(filename);
326 file_info_.play_thread_open = false; 290 stream_data_.eof = false;
327 file_info_.has_replaygain = false; 291 stream_data_.play_thread_open = false;
328 292 stream_data_.has_replaygain = false;
329 if (source_to_decoder_type (filename) == DECODER_FILE) { 293
294 if(!is_http_source(filename)) {
330 if(0 == (f = fopen(filename, "r"))) 295 if(0 == (f = fopen(filename, "r")))
331 return; 296 return;
332 fclose(f); 297 fclose(f);
333 } 298 }
334 299
335 if(decoder_ == 0) 300 if(decoder_ == 0)
336 return; 301 return;
337 302
338 if(!safe_decoder_init_(filename, &decoder_, &decoder_func_table_)) 303 if(!safe_decoder_init_(filename, decoder_))
339 return; 304 return;
340 305
341 if(file_info_.has_replaygain && flac_cfg.output.replaygain.enable) { 306 if(stream_data_.has_replaygain && flac_cfg.output.replaygain.enable) {
342 if(flac_cfg.output.resolution.replaygain.bps_out == 8) { 307 if(flac_cfg.output.resolution.replaygain.bps_out == 8) {
343 file_info_.sample_format = FMT_U8; 308 stream_data_.sample_format = FMT_U8;
344 file_info_.sample_format_bytes_per_sample = 1; 309 stream_data_.sample_format_bytes_per_sample = 1;
345 } 310 }
346 else if(flac_cfg.output.resolution.replaygain.bps_out == 16) { 311 else if(flac_cfg.output.resolution.replaygain.bps_out == 16) {
347 file_info_.sample_format = (is_big_endian_host_) ? FMT_S16_BE : FMT_S16_LE; 312 stream_data_.sample_format = (is_big_endian_host_) ? FMT_S16_BE : FMT_S16_LE;
348 file_info_.sample_format_bytes_per_sample = 2; 313 stream_data_.sample_format_bytes_per_sample = 2;
349 } 314 }
350 else { 315 else {
351 /*@@@ 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); */ 316 /*@@@ 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); */
352 fprintf(stderr, "libxmms-flac: can't handle %d bit output\n", flac_cfg.output.resolution.replaygain.bps_out); 317 fprintf(stderr, "libxmms-flac: can't handle %d bit output\n", flac_cfg.output.resolution.replaygain.bps_out);
353 decoder_func_table_ -> safe_decoder_finish(decoder_); 318 safe_decoder_finish_(decoder_);
354 return; 319 return;
355 } 320 }
356 } 321 }
357 else { 322 else {
358 if(file_info_.bits_per_sample == 8) { 323 if(stream_data_.bits_per_sample == 8) {
359 file_info_.sample_format = FMT_U8; 324 stream_data_.sample_format = FMT_U8;
360 file_info_.sample_format_bytes_per_sample = 1; 325 stream_data_.sample_format_bytes_per_sample = 1;
361 } 326 }
362 else if(file_info_.bits_per_sample == 16 || (file_info_.bits_per_sample == 24 && flac_cfg.output.resolution.normal.dither_24_to_16)) { 327 else if(stream_data_.bits_per_sample == 16 || (stream_data_.bits_per_sample == 24 && flac_cfg.output.resolution.normal.dither_24_to_16)) {
363 file_info_.sample_format = (is_big_endian_host_) ? FMT_S16_BE : FMT_S16_LE; 328 stream_data_.sample_format = (is_big_endian_host_) ? FMT_S16_BE : FMT_S16_LE;
364 file_info_.sample_format_bytes_per_sample = 2; 329 stream_data_.sample_format_bytes_per_sample = 2;
365 } 330 }
366 else { 331 else {
367 /*@@@ 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); */ 332 /*@@@ 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); */
368 fprintf(stderr, "libxmms-flac: can't handle %d bit output\n", file_info_.bits_per_sample); 333 fprintf(stderr, "libxmms-flac: can't handle %d bit output\n", stream_data_.bits_per_sample);
369 decoder_func_table_ -> safe_decoder_finish(decoder_); 334 safe_decoder_finish_(decoder_);
370 return; 335 return;
371 } 336 }
372 } 337 }
373 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); 338 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);
374 file_info_.is_playing = true; 339 stream_data_.is_playing = true;
375 340
376 if(flac_ip.output->open_audio(file_info_.sample_format, file_info_.sample_rate, file_info_.channels) == 0) { 341 if(flac_ip.output->open_audio(stream_data_.sample_format, stream_data_.sample_rate, stream_data_.channels) == 0) {
377 audio_error_ = true; 342 audio_error_ = true;
378 decoder_func_table_ -> safe_decoder_finish(decoder_); 343 safe_decoder_finish_(decoder_);
379 return; 344 return;
380 } 345 }
381 346
382 file_info_.title = flac_format_song_title(filename); 347 stream_data_.title = flac_format_song_title(filename);
383 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); 348 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);
384 349
385 file_info_.seek_to_in_sec = -1; 350 stream_data_.seek_to_in_sec = -1;
386 file_info_.play_thread_open = true; 351 stream_data_.play_thread_open = true;
387 decode_thread_ = g_thread_create((GThreadFunc)play_loop_, NULL, TRUE, NULL); 352 decode_thread_ = g_thread_create((GThreadFunc)play_loop_, NULL, TRUE, NULL);
388 } 353 }
389 354
390 void FLAC_XMMS__stop() 355 void FLAC_XMMS__stop()
391 { 356 {
392 if(file_info_.is_playing) { 357 if(stream_data_.is_playing) {
393 file_info_.is_playing = false; 358 stream_data_.is_playing = false;
394 if(file_info_.play_thread_open) { 359 if(stream_data_.play_thread_open) {
395 file_info_.play_thread_open = false; 360 stream_data_.play_thread_open = false;
396 g_thread_join(decode_thread_); 361 g_thread_join(decode_thread_);
397 } 362 }
398 flac_ip.output->close_audio(); 363 flac_ip.output->close_audio();
399 decoder_func_table_ -> safe_decoder_finish (decoder_); 364 safe_decoder_finish_(decoder_);
400 } 365 }
401 } 366 }
402 367
403 void FLAC_XMMS__pause(short p) 368 void FLAC_XMMS__pause(short p)
404 { 369 {
405 flac_ip.output->pause(p); 370 flac_ip.output->pause(p);
406 } 371 }
407 372
408 void FLAC_XMMS__seek(int time) 373 void FLAC_XMMS__seek(int time)
409 { 374 {
410 if (decoder_func_table_->seekable) { 375 if(!stream_data_.is_http_source) {
411 file_info_.seek_to_in_sec = time; 376 stream_data_.seek_to_in_sec = time;
412 file_info_.eof = false; 377 stream_data_.eof = false;
413 378
414 while(file_info_.seek_to_in_sec != -1) 379 while(stream_data_.seek_to_in_sec != -1)
415 xmms_usleep(10000); 380 xmms_usleep(10000);
416 } 381 }
417 } 382 }
418 383
419 int FLAC_XMMS__get_time() 384 int FLAC_XMMS__get_time()
420 { 385 {
421 if(audio_error_) 386 if(audio_error_)
422 return -2; 387 return -2;
423 if(!file_info_.is_playing || (file_info_.eof && !flac_ip.output->buffer_playing())) 388 if(!stream_data_.is_playing || (stream_data_.eof && !flac_ip.output->buffer_playing()))
424 return -1; 389 return -1;
425 else 390 else
426 return flac_ip.output->output_time(); 391 return flac_ip.output->output_time();
427 } 392 }
428 393
455 if (flac_cfg.stream.proxy_pass) { 420 if (flac_cfg.stream.proxy_pass) {
456 free(flac_cfg.stream.proxy_pass); 421 free(flac_cfg.stream.proxy_pass);
457 flac_cfg.stream.proxy_pass = NULL; 422 flac_cfg.stream.proxy_pass = NULL;
458 } 423 }
459 424
460 decoder_func_table_ -> safe_decoder_delete(decoder_); 425 safe_decoder_delete_(decoder_);
461 decoder_ = 0; 426 decoder_ = 0;
462 } 427 }
463 428
464 void FLAC_XMMS__get_song_info(char *filename, char **title, int *length_in_msec) 429 void FLAC_XMMS__get_song_info(char *filename, char **title, int *length_in_msec)
465 { 430 {
469 filename = ""; 434 filename = "";
470 435
471 if(!FLAC__metadata_get_streaminfo(filename, &streaminfo)) { 436 if(!FLAC__metadata_get_streaminfo(filename, &streaminfo)) {
472 /* @@@ how to report the error? */ 437 /* @@@ how to report the error? */
473 if(title) { 438 if(title) {
474 if (source_to_decoder_type (filename) == DECODER_FILE) { 439 if (!is_http_source(filename)) {
475 static const char *errtitle = "Invalid FLAC File: "; 440 static const char *errtitle = "Invalid FLAC File: ";
476 *title = g_malloc(strlen(errtitle) + 1 + strlen(filename) + 1 + 1); 441 *title = g_malloc(strlen(errtitle) + 1 + strlen(filename) + 1 + 1);
477 sprintf(*title, "%s\"%s\"", errtitle, filename); 442 sprintf(*title, "%s\"%s\"", errtitle, filename);
478 } else { 443 } else {
479 *title = NULL; 444 *title = NULL;
485 } 450 }
486 451
487 if(title) { 452 if(title) {
488 *title = flac_format_song_title(filename); 453 *title = flac_format_song_title(filename);
489 } 454 }
490 if(length_in_msec) 455 if(length_in_msec) {
491 *length_in_msec = (unsigned)((double)streaminfo.data.stream_info.total_samples / (double)streaminfo.data.stream_info.sample_rate * 1000.0 + 0.5); 456 FLAC__uint64 l = (FLAC__uint64)((double)streaminfo.data.stream_info.total_samples / (double)streaminfo.data.stream_info.sample_rate * 1000.0 + 0.5);
457 if (l > INT_MAX)
458 l = INT_MAX;
459 *length_in_msec = (int)l;
460 }
492 } 461 }
493 462
494 /*********************************************************************** 463 /***********************************************************************
495 * local routines 464 * local routines
496 **********************************************************************/ 465 **********************************************************************/
500 unsigned written_time_last = 0, bh_index_last_w = 0, bh_index_last_o = BITRATE_HIST_SIZE, blocksize = 1; 469 unsigned written_time_last = 0, bh_index_last_w = 0, bh_index_last_o = BITRATE_HIST_SIZE, blocksize = 1;
501 FLAC__uint64 decode_position_last = 0, decode_position_frame_last = 0, decode_position_frame = 0; 470 FLAC__uint64 decode_position_last = 0, decode_position_frame_last = 0, decode_position_frame = 0;
502 471
503 (void)arg; 472 (void)arg;
504 473
505 while(file_info_.is_playing) { 474 while(stream_data_.is_playing) {
506 if(!file_info_.eof) { 475 if(!stream_data_.eof) {
507 while(sample_buffer_last_ - sample_buffer_first_ < SAMPLES_PER_WRITE) { 476 while(sample_buffer_last_ - sample_buffer_first_ < SAMPLES_PER_WRITE) {
508 unsigned s; 477 unsigned s;
509 478
510 s = sample_buffer_last_ - sample_buffer_first_; 479 s = sample_buffer_last_ - sample_buffer_first_;
511 if(decoder_func_table_ -> is_eof(decoder_)) { 480 if(FLAC__stream_decoder_get_state(decoder_) == FLAC__STREAM_DECODER_END_OF_STREAM) {
512 file_info_.eof = true; 481 stream_data_.eof = true;
513 break; 482 break;
514 } 483 }
515 else if (!decoder_func_table_ -> process_single(decoder_)) { 484 else if(!FLAC__stream_decoder_process_single(decoder_)) {
516 /*@@@ this should probably be a dialog */ 485 /*@@@ this should probably be a dialog */
517 fprintf(stderr, "libxmms-flac: READ ERROR processing frame\n"); 486 fprintf(stderr, "libxmms-flac: READ ERROR processing frame\n");
518 file_info_.eof = true; 487 stream_data_.eof = true;
519 break; 488 break;
520 } 489 }
521 blocksize = sample_buffer_last_ - sample_buffer_first_ - s; 490 blocksize = sample_buffer_last_ - sample_buffer_first_ - s;
522 decode_position_frame_last = decode_position_frame; 491 decode_position_frame_last = decode_position_frame;
523 if(!decoder_func_table_->seekable || !FLAC__file_decoder_get_decode_position(decoder_, &decode_position_frame)) 492 if(stream_data_.is_http_source || !FLAC__stream_decoder_get_decode_position(decoder_, &decode_position_frame))
524 decode_position_frame = 0; 493 decode_position_frame = 0;
525 } 494 }
526 if(sample_buffer_last_ - sample_buffer_first_ > 0) { 495 if(sample_buffer_last_ - sample_buffer_first_ > 0) {
527 const unsigned n = min(sample_buffer_last_ - sample_buffer_first_, SAMPLES_PER_WRITE); 496 const unsigned n = min(sample_buffer_last_ - sample_buffer_first_, SAMPLES_PER_WRITE);
528 int bytes = n * file_info_.channels * file_info_.sample_format_bytes_per_sample; 497 int bytes = n * stream_data_.channels * stream_data_.sample_format_bytes_per_sample;
529 FLAC__byte *sample_buffer_start = sample_buffer_ + sample_buffer_first_ * file_info_.channels * file_info_.sample_format_bytes_per_sample; 498 FLAC__byte *sample_buffer_start = sample_buffer_ + sample_buffer_first_ * stream_data_.channels * stream_data_.sample_format_bytes_per_sample;
530 unsigned written_time, bh_index_w; 499 unsigned written_time, bh_index_w;
531 FLAC__uint64 decode_position; 500 FLAC__uint64 decode_position;
532 501
533 sample_buffer_first_ += n; 502 sample_buffer_first_ += n;
534 while(flac_ip.output->buffer_free() < (int)bytes && file_info_.is_playing && file_info_.seek_to_in_sec == -1) 503 while(flac_ip.output->buffer_free() < (int)bytes && stream_data_.is_playing && stream_data_.seek_to_in_sec == -1)
535 xmms_usleep(10000); 504 xmms_usleep(10000);
536 if(file_info_.is_playing && file_info_.seek_to_in_sec == -1) 505 if(stream_data_.is_playing && stream_data_.seek_to_in_sec == -1)
537 produce_audio(flac_ip.output->written_time(), file_info_.sample_format, 506 produce_audio(flac_ip.output->written_time(), stream_data_.sample_format,
538 file_info_.channels, bytes, sample_buffer_start, NULL); 507 stream_data_.channels, bytes, sample_buffer_start, NULL);
539 508
540 /* compute current bitrate */ 509 /* compute current bitrate */
541 510
542 written_time = flac_ip.output->written_time(); 511 written_time = flac_ip.output->written_time();
543 bh_index_w = written_time / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE; 512 bh_index_w = written_time / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
545 bh_index_last_w = bh_index_w; 514 bh_index_last_w = bh_index_w;
546 decode_position = decode_position_frame - (double)(sample_buffer_last_ - sample_buffer_first_) * (double)(decode_position_frame - decode_position_frame_last) / (double)blocksize; 515 decode_position = decode_position_frame - (double)(sample_buffer_last_ - sample_buffer_first_) * (double)(decode_position_frame - decode_position_frame_last) / (double)blocksize;
547 bitrate_history_[(bh_index_w + BITRATE_HIST_SIZE - 1) % BITRATE_HIST_SIZE] = 516 bitrate_history_[(bh_index_w + BITRATE_HIST_SIZE - 1) % BITRATE_HIST_SIZE] =
548 decode_position > decode_position_last && written_time > written_time_last ? 517 decode_position > decode_position_last && written_time > written_time_last ?
549 8000 * (decode_position - decode_position_last) / (written_time - written_time_last) : 518 8000 * (decode_position - decode_position_last) / (written_time - written_time_last) :
550 file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample; 519 stream_data_.sample_rate * stream_data_.channels * stream_data_.bits_per_sample;
551 decode_position_last = decode_position; 520 decode_position_last = decode_position;
552 written_time_last = written_time; 521 written_time_last = written_time;
553 } 522 }
554 } 523 }
555 else { 524 else {
556 file_info_.eof = true; 525 stream_data_.eof = true;
557 xmms_usleep(10000); 526 xmms_usleep(10000);
558 } 527 }
559 } 528 }
560 else 529 else
561 xmms_usleep(10000); 530 xmms_usleep(10000);
562 if(decoder_func_table_->seekable && file_info_.seek_to_in_sec != -1) { 531 if(!stream_data_.is_http_source && stream_data_.seek_to_in_sec != -1) {
563 const double distance = (double)file_info_.seek_to_in_sec * 1000.0 / (double)file_info_.length_in_msec; 532 const double distance = (double)stream_data_.seek_to_in_sec * 1000.0 / (double)stream_data_.length_in_msec;
564 unsigned target_sample = (unsigned)(distance * (double)file_info_.total_samples); 533 FLAC__uint64 target_sample = (FLAC__uint64)(distance * (double)stream_data_.total_samples);
565 if(FLAC__file_decoder_seek_absolute(decoder_, (FLAC__uint64)target_sample)) { 534 if(stream_data_.total_samples > 0 && target_sample >= stream_data_.total_samples)
566 flac_ip.output->flush(file_info_.seek_to_in_sec * 1000); 535 target_sample = stream_data_.total_samples - 1;
536 if(FLAC__stream_decoder_seek_absolute(decoder_, target_sample)) {
537 flac_ip.output->flush(stream_data_.seek_to_in_sec * 1000);
567 bh_index_last_w = bh_index_last_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE; 538 bh_index_last_w = bh_index_last_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
568 if(!FLAC__file_decoder_get_decode_position(decoder_, &decode_position_frame)) 539 if(!FLAC__stream_decoder_get_decode_position(decoder_, &decode_position_frame))
569 decode_position_frame = 0; 540 decode_position_frame = 0;
570 file_info_.seek_to_in_sec = -1; 541 stream_data_.eof = false;
571 file_info_.eof = false;
572 sample_buffer_first_ = sample_buffer_last_ = 0; 542 sample_buffer_first_ = sample_buffer_last_ = 0;
573 } 543 }
544 else if(FLAC__stream_decoder_get_state(decoder_) == FLAC__STREAM_DECODER_SEEK_ERROR) {
545 /*@@@ this should probably be a dialog */
546 fprintf(stderr, "libxmms-flac: SEEK ERROR\n");
547 FLAC__stream_decoder_flush(decoder_);
548 stream_data_.eof = false;
549 sample_buffer_first_ = sample_buffer_last_ = 0;
550 }
551 stream_data_.seek_to_in_sec = -1;
574 } 552 }
575 else { 553 else {
576 /* display the right bitrate from history */ 554 /* display the right bitrate from history */
577 unsigned bh_index_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE; 555 unsigned bh_index_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
578 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) { 556 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) {
579 bh_index_last_o = bh_index_o; 557 bh_index_last_o = bh_index_o;
580 flac_ip.set_info(file_info_.title, file_info_.length_in_msec, bitrate_history_[bh_index_o], file_info_.sample_rate, file_info_.channels); 558 flac_ip.set_info(stream_data_.title, stream_data_.length_in_msec, bitrate_history_[bh_index_o], stream_data_.sample_rate, stream_data_.channels);
581 } 559 }
582 } 560 }
583 } 561 }
584 562
585 decoder_func_table_ -> safe_decoder_finish(decoder_); 563 safe_decoder_finish_(decoder_);
586 564
587 /* are these two calls necessary? */ 565 /* are these two calls necessary? */
588 flac_ip.output->buffer_free(); 566 flac_ip.output->buffer_free();
589 flac_ip.output->buffer_free(); 567 flac_ip.output->buffer_free();
590 568
591 g_free(file_info_.title); 569 g_free(stream_data_.title);
592 570
593 g_thread_exit(NULL); 571 g_thread_exit(NULL);
594 return 0; /* to silence the compiler warning about not returning a value */ 572 return 0; /* to silence the compiler warning about not returning a value */
595 } 573 }
596 574
597 /*********** File decoder functions */ 575 FLAC__bool safe_decoder_init_(const char *filename, FLAC__StreamDecoder *decoder)
598 576 {
599 static FLAC__bool file_decoder_init (void *decoder) 577 if(decoder == 0)
600 { 578 return false;
601 return FLAC__file_decoder_init( (FLAC__FileDecoder*) decoder) == FLAC__FILE_DECODER_OK; 579
602 } 580 safe_decoder_finish_(decoder);
603 581
604 static void file_decoder_safe_decoder_finish_(void *decoder) 582 FLAC__stream_decoder_set_md5_checking(decoder, false);
605 { 583 FLAC__stream_decoder_set_metadata_ignore_all(decoder);
606 if(decoder && FLAC__file_decoder_get_state((FLAC__FileDecoder *) decoder) != FLAC__FILE_DECODER_UNINITIALIZED) 584 FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
607 FLAC__file_decoder_finish((FLAC__FileDecoder *) decoder); 585 FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
608 } 586 if(stream_data_.is_http_source) {
609 587 flac_http_open(filename, 0);
610 static void file_decoder_safe_decoder_delete_(void *decoder) 588 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)
589 return false;
590 }
591 else {
592 if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/&stream_data_) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
593 return false;
594 }
595
596 if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
597 return false;
598
599 return true;
600 }
601
602 void safe_decoder_finish_(FLAC__StreamDecoder *decoder)
603 {
604 if(decoder && FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_UNINITIALIZED)
605 FLAC__stream_decoder_finish(decoder);
606 if(stream_data_.is_http_source)
607 flac_http_close();
608 }
609
610 void safe_decoder_delete_(FLAC__StreamDecoder *decoder)
611 { 611 {
612 if(decoder) { 612 if(decoder) {
613 file_decoder_safe_decoder_finish_(decoder); 613 safe_decoder_finish_(decoder);
614 FLAC__file_decoder_delete( (FLAC__FileDecoder *) decoder); 614 FLAC__stream_decoder_delete(decoder);
615 } 615 }
616 } 616 }
617 617
618 static FLAC__bool file_decoder_is_eof(void *decoder) 618 FLAC__StreamDecoderReadStatus http_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
619 { 619 {
620 return FLAC__file_decoder_get_state((FLAC__FileDecoder *) decoder) == FLAC__FILE_DECODER_END_OF_FILE; 620 (void)decoder;
621 } 621 (void)client_data;
622 622 *bytes = flac_http_read(buffer, *bytes);
623 static const decoder_funcs_t FILE_DECODER_FUNCTIONS = {
624 true,
625 (void* (*) (void)) FLAC__file_decoder_new,
626 (FLAC__bool (*) (void *, FLAC__bool)) FLAC__file_decoder_set_md5_checking,
627 (FLAC__bool (*) (void *, const char*)) FLAC__file_decoder_set_filename,
628 (FLAC__bool (*) (void *)) FLAC__file_decoder_set_metadata_ignore_all,
629 (FLAC__bool (*) (void *, FLAC__MetadataType)) FLAC__file_decoder_set_metadata_respond,
630 (FLAC__bool (*) (void *, WriteCallback)) FLAC__file_decoder_set_write_callback,
631 (FLAC__bool (*) (void *, MetadataCallback)) FLAC__file_decoder_set_metadata_callback,
632 (FLAC__bool (*) (void *, ErrorCallback)) FLAC__file_decoder_set_error_callback,
633 (FLAC__bool (*) (void *, void *)) FLAC__file_decoder_set_client_data,
634 (FLAC__bool (*) (void *)) file_decoder_init,
635 (void (*) (void *)) file_decoder_safe_decoder_finish_,
636 (void (*) (void *)) file_decoder_safe_decoder_delete_,
637 (FLAC__bool (*) (void *)) FLAC__file_decoder_process_until_end_of_metadata,
638 (FLAC__bool (*) (void *)) FLAC__file_decoder_process_single,
639 file_decoder_is_eof
640 };
641
642 /*********** HTTP decoder functions */
643
644 static gchar *url_;
645
646 static FLAC__bool http_decoder_set_md5_checking (void *decoder, FLAC__bool value)
647 {
648 (void) value;
649 // operation unsupported
650 return FLAC__stream_decoder_get_state ((const FLAC__StreamDecoder *) decoder) ==
651 FLAC__STREAM_DECODER_UNINITIALIZED;
652 }
653
654 static FLAC__bool http_decoder_set_url (void *decoder, const char* url)
655 {
656 (void) decoder;
657 url_ = g_strdup (url);
658 return true;
659 }
660
661 static FLAC__StreamDecoderReadStatus http_decoder_read_callback (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
662 {
663 (void) decoder;
664 (void) client_data;
665 *bytes = flac_http_read (buffer, *bytes);
666 return *bytes ? FLAC__STREAM_DECODER_READ_STATUS_CONTINUE : FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; 623 return *bytes ? FLAC__STREAM_DECODER_READ_STATUS_CONTINUE : FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
667 } 624 }
668 625
669 static FLAC__bool http_decoder_init (void *decoder) 626 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
670 { 627 {
671 flac_http_open (url_, 0); 628 stream_data_struct *stream_data = (stream_data_struct *)client_data;
672 g_free (url_); 629 const unsigned channels = stream_data->channels, wide_samples = frame->header.blocksize;
673 FLAC__stream_decoder_set_read_callback (decoder, http_decoder_read_callback); 630 const unsigned bits_per_sample = stream_data->bits_per_sample;
674 return FLAC__stream_decoder_init( (FLAC__StreamDecoder*) decoder) == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;
675 }
676
677 static void http_decoder_safe_decoder_finish_(void *decoder)
678 {
679 if(decoder && FLAC__stream_decoder_get_state((FLAC__StreamDecoder *) decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) {
680 FLAC__stream_decoder_finish((FLAC__StreamDecoder *) decoder);
681 flac_http_close();
682 }
683 }
684
685 static void http_decoder_safe_decoder_delete_(void *decoder)
686 {
687 if(decoder) {
688 http_decoder_safe_decoder_finish_(decoder);
689 FLAC__stream_decoder_delete( (FLAC__StreamDecoder *) decoder);
690 }
691 }
692
693 static FLAC__bool http_decoder_is_eof(void *decoder)
694 {
695 return FLAC__stream_decoder_get_state((FLAC__StreamDecoder *) decoder) == FLAC__STREAM_DECODER_END_OF_STREAM;
696 }
697
698 static const decoder_funcs_t HTTP_DECODER_FUNCTIONS = {
699 false,
700 (void* (*) (void)) FLAC__stream_decoder_new,
701 http_decoder_set_md5_checking,
702 (FLAC__bool (*) (void *, const char*)) http_decoder_set_url,
703 (FLAC__bool (*) (void *)) FLAC__stream_decoder_set_metadata_ignore_all,
704 (FLAC__bool (*) (void *, FLAC__MetadataType)) FLAC__stream_decoder_set_metadata_respond,
705 (FLAC__bool (*) (void *, WriteCallback)) FLAC__stream_decoder_set_write_callback,
706 (FLAC__bool (*) (void *, MetadataCallback)) FLAC__stream_decoder_set_metadata_callback,
707 (FLAC__bool (*) (void *, ErrorCallback)) FLAC__stream_decoder_set_error_callback,
708 (FLAC__bool (*) (void *, void *)) FLAC__stream_decoder_set_client_data,
709 (FLAC__bool (*) (void *)) http_decoder_init,
710 (void (*) (void *)) http_decoder_safe_decoder_finish_,
711 (void (*) (void *)) http_decoder_safe_decoder_delete_,
712 (FLAC__bool (*) (void *)) FLAC__stream_decoder_process_until_end_of_metadata,
713 (FLAC__bool (*) (void *)) FLAC__stream_decoder_process_single,
714 http_decoder_is_eof
715 };
716
717 static decoder_funcs_t const *decoder_func_table_;
718
719 static void init_decoder_func_tables()
720 {
721 DECODER_FUNCS [DECODER_FILE] = & FILE_DECODER_FUNCTIONS;
722 DECODER_FUNCS [DECODER_HTTP] = & HTTP_DECODER_FUNCTIONS;
723 }
724
725 static decoder_t source_to_decoder_type (const char *source)
726 {
727 return strncasecmp(source, "http://", 7) ? DECODER_FILE : DECODER_HTTP;
728 }
729
730 static void change_decoder_if_needed (decoder_t new_decoder_type, void **decoderp, decoder_funcs_t const ** fntabp)
731 {
732 const decoder_funcs_t *new_fn_table = DECODER_FUNCS [new_decoder_type];
733 if (*fntabp != new_fn_table) {
734 (*fntabp)->safe_decoder_delete(*decoderp);
735 *fntabp = new_fn_table;
736 *decoderp = new_fn_table -> new_decoder();
737 }
738 }
739
740 FLAC__bool safe_decoder_init_(const char *filename, void **decoderp, decoder_funcs_t const ** fntabp)
741 {
742 if(decoderp == 0 || *decoderp == 0)
743 return false;
744
745 (*fntabp)->safe_decoder_finish(*decoderp);
746
747 change_decoder_if_needed(source_to_decoder_type(filename), decoderp, fntabp);
748
749 {
750 decoder_funcs_t const *fntab = *fntabp;
751 void *decoder = *decoderp;
752
753 decoder = *decoderp;
754 fntab = *fntabp;
755
756 fntab -> set_md5_checking(decoder, false);
757 fntab -> set_source(decoder, filename);
758 fntab -> set_metadata_ignore_all(decoder);
759 fntab -> set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
760 fntab -> set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
761 fntab -> set_write_callback(decoder, write_callback_);
762 fntab -> set_metadata_callback(decoder, metadata_callback_);
763 fntab -> set_error_callback(decoder, error_callback_);
764 fntab -> set_client_data(decoder, &file_info_);
765 if(!fntab -> decoder_init(decoder))
766 return false;
767
768 if(!fntab -> process_until_end_of_metadata(decoder))
769 return false;
770 }
771
772 return true;
773 }
774
775 FLAC__StreamDecoderWriteStatus write_callback_(const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
776 {
777 file_info_struct *file_info = (file_info_struct *)client_data;
778 const unsigned channels = file_info->channels, wide_samples = frame->header.blocksize;
779 const unsigned bits_per_sample = file_info->bits_per_sample;
780 FLAC__byte *sample_buffer_start; 631 FLAC__byte *sample_buffer_start;
781 632
782 (void)decoder; 633 (void)decoder;
783 634
784 if(file_info->abort_flag) 635 if(stream_data->abort_flag)
785 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; 636 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
786 637
787 if((sample_buffer_last_ + wide_samples) > (SAMPLE_BUFFER_SIZE / (channels * file_info->sample_format_bytes_per_sample))) { 638 if((sample_buffer_last_ + wide_samples) > (SAMPLE_BUFFER_SIZE / (channels * stream_data->sample_format_bytes_per_sample))) {
788 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); 639 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);
789 sample_buffer_last_ -= sample_buffer_first_; 640 sample_buffer_last_ -= sample_buffer_first_;
790 sample_buffer_first_ = 0; 641 sample_buffer_first_ = 0;
791 } 642 }
792 sample_buffer_start = sample_buffer_ + sample_buffer_last_ * channels * file_info->sample_format_bytes_per_sample; 643 sample_buffer_start = sample_buffer_ + sample_buffer_last_ * channels * stream_data->sample_format_bytes_per_sample;
793 if(file_info->has_replaygain && flac_cfg.output.replaygain.enable) { 644 if(stream_data->has_replaygain && flac_cfg.output.replaygain.enable) {
794 FLAC__replaygain_synthesis__apply_gain( 645 FLAC__replaygain_synthesis__apply_gain(
795 sample_buffer_start, 646 sample_buffer_start,
796 !is_big_endian_host_, 647 !is_big_endian_host_,
797 file_info->sample_format_bytes_per_sample == 1, /* unsigned_data_out */ 648 stream_data->sample_format_bytes_per_sample == 1, /* unsigned_data_out */
798 buffer, 649 buffer,
799 wide_samples, 650 wide_samples,
800 channels, 651 channels,
801 bits_per_sample, 652 bits_per_sample,
802 file_info->sample_format_bytes_per_sample * 8, 653 stream_data->sample_format_bytes_per_sample * 8,
803 file_info->replay_scale, 654 stream_data->replay_scale,
804 flac_cfg.output.replaygain.hard_limit, 655 flac_cfg.output.replaygain.hard_limit,
805 flac_cfg.output.resolution.replaygain.dither, 656 flac_cfg.output.resolution.replaygain.dither,
806 &file_info->dither_context 657 &stream_data->dither_context
807 ); 658 );
808 } 659 }
809 else if(is_big_endian_host_) { 660 else if(is_big_endian_host_) {
810 FLAC__plugin_common__pack_pcm_signed_big_endian( 661 FLAC__plugin_common__pack_pcm_signed_big_endian(
811 sample_buffer_start, 662 sample_buffer_start,
812 buffer, 663 buffer,
813 wide_samples, 664 wide_samples,
814 channels, 665 channels,
815 bits_per_sample, 666 bits_per_sample,
816 file_info->sample_format_bytes_per_sample * 8 667 stream_data->sample_format_bytes_per_sample * 8
817 ); 668 );
818 } 669 }
819 else { 670 else {
820 FLAC__plugin_common__pack_pcm_signed_little_endian( 671 FLAC__plugin_common__pack_pcm_signed_little_endian(
821 sample_buffer_start, 672 sample_buffer_start,
822 buffer, 673 buffer,
823 wide_samples, 674 wide_samples,
824 channels, 675 channels,
825 bits_per_sample, 676 bits_per_sample,
826 file_info->sample_format_bytes_per_sample * 8 677 stream_data->sample_format_bytes_per_sample * 8
827 ); 678 );
828 } 679 }
829 680
830 sample_buffer_last_ += wide_samples; 681 sample_buffer_last_ += wide_samples;
831 682
832 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; 683 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
833 } 684 }
834 685
835 void metadata_callback_(const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data) 686 void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
836 { 687 {
837 file_info_struct *file_info = (file_info_struct *)client_data; 688 stream_data_struct *stream_data = (stream_data_struct *)client_data;
838 (void)decoder; 689 (void)decoder;
839 if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { 690 if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
840 FLAC__ASSERT(metadata->data.stream_info.total_samples < FLAC__U64L(0x100000000)); /* this plugin can only handle < 4 gigasamples */ 691 stream_data->total_samples = metadata->data.stream_info.total_samples;
841 file_info->total_samples = (unsigned)(metadata->data.stream_info.total_samples&0xffffffff); 692 stream_data->bits_per_sample = metadata->data.stream_info.bits_per_sample;
842 file_info->bits_per_sample = metadata->data.stream_info.bits_per_sample; 693 stream_data->channels = metadata->data.stream_info.channels;
843 file_info->channels = metadata->data.stream_info.channels; 694 stream_data->sample_rate = metadata->data.stream_info.sample_rate;
844 file_info->sample_rate = metadata->data.stream_info.sample_rate; 695 {
845 file_info->length_in_msec = (unsigned)((double)file_info->total_samples / (double)file_info->sample_rate * 1000.0 + 0.5); 696 FLAC__uint64 l = (FLAC__uint64)((double)stream_data->total_samples / (double)stream_data->sample_rate * 1000.0 + 0.5);
697 if (l > INT_MAX)
698 l = INT_MAX;
699 stream_data->length_in_msec = (int)l;
700 }
846 } 701 }
847 else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { 702 else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
848 double gain, peak; 703 double reference, gain, peak;
849 if(grabbag__replaygain_load_from_vorbiscomment(metadata, flac_cfg.output.replaygain.album_mode, &gain, &peak)) { 704 if(grabbag__replaygain_load_from_vorbiscomment(metadata, flac_cfg.output.replaygain.album_mode, /*strict=*/false, &reference, &gain, &peak)) {
850 file_info->has_replaygain = true; 705 stream_data->has_replaygain = true;
851 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); 706 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);
852 } 707 }
853 } 708 }
854 } 709 }
855 710
856 void error_callback_(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) 711 void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
857 { 712 {
858 file_info_struct *file_info = (file_info_struct *)client_data; 713 stream_data_struct *stream_data = (stream_data_struct *)client_data;
859 (void)decoder; 714 (void)decoder;
860 if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) 715 if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC)
861 file_info->abort_flag = true; 716 stream_data->abort_flag = true;
862 } 717 }