comparison src/flac112/plugin.c @ 511:5f2145032f46 trunk

[svn] - removed http code from flac 112 plugin; still have to remove http options from gui
author giacomo
date Mon, 22 Jan 2007 08:27:39 -0800
parents 0dd1ff7e5ba7
children 5be9b8f7ac03
comparison
equal deleted inserted replaced
510:48e9efba7eb0 511:5f2145032f46
43 #include "plugin_common/all.h" 43 #include "plugin_common/all.h"
44 #include "grabbag.h" 44 #include "grabbag.h"
45 #include "replaygain_synthesis.h" 45 #include "replaygain_synthesis.h"
46 #include "configure.h" 46 #include "configure.h"
47 #include "charset.h" 47 #include "charset.h"
48 #include "http.h"
49 #include "tag.h" 48 #include "tag.h"
50 49
51 #ifdef min 50 #ifdef min
52 #undef min 51 #undef min
53 #endif 52 #endif
84 83
85 typedef FLAC__StreamDecoderWriteStatus (*WriteCallback) (const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); 84 typedef FLAC__StreamDecoderWriteStatus (*WriteCallback) (const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
86 typedef void (*MetadataCallback) (const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data); 85 typedef void (*MetadataCallback) (const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
87 typedef void (*ErrorCallback) (const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); 86 typedef void (*ErrorCallback) (const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
88 87
89 typedef struct { 88 #define NUM_DECODER_TYPES 1
90 FLAC__bool seekable;
91 void* (*new_decoder) (void);
92 FLAC__bool (*set_source) (void *decoder, const char* source);
93 FLAC__bool (*unset_source) (void *decoder);
94 FLAC__bool (*set_md5_checking) (void *decoder, FLAC__bool value);
95 FLAC__bool (*set_metadata_ignore_all) (void *decoder);
96 FLAC__bool (*set_metadata_respond) (void *decoder, FLAC__MetadataType type);
97 FLAC__bool (*set_write_callback) (void *decoder, WriteCallback value);
98 FLAC__bool (*set_metadata_callback) (void *decoder, MetadataCallback value);
99 FLAC__bool (*set_error_callback) (void *decoder, ErrorCallback value);
100 FLAC__bool (*set_client_data) (void *decoder, void *value);
101 FLAC__bool (*decoder_init) (void *decoder);
102 void (*safe_decoder_finish) (void *decoder);
103 void (*safe_decoder_delete) (void *decoder);
104 FLAC__bool (*process_until_end_of_metadata) (void *decoder);
105 FLAC__bool (*process_single) (void *decoder);
106 FLAC__bool (*is_eof) (void *decoder);
107 } decoder_funcs_t;
108
109 #define NUM_DECODER_TYPES 2
110 typedef enum { 89 typedef enum {
111 DECODER_FILE, 90 DECODER_FILE
112 DECODER_HTTP
113 } decoder_t; 91 } decoder_t;
114 92
115 static void FLAC_XMMS__init(); 93 static void FLAC_XMMS__init();
116 static int FLAC_XMMS__is_our_file(char *filename); 94 static int FLAC_XMMS__is_our_file(char *filename);
117 static int FLAC_XMMS__is_our_file_from_vfs(char *filename, VFSFile *vfsfile); 95 static int FLAC_XMMS__is_our_file_from_vfs(char *filename, VFSFile *vfsfile);
123 static void FLAC_XMMS__cleanup(); 101 static void FLAC_XMMS__cleanup();
124 static void FLAC_XMMS__get_song_info(char *filename, char **title, int *length); 102 static void FLAC_XMMS__get_song_info(char *filename, char **title, int *length);
125 103
126 static void *play_loop_(void *arg); 104 static void *play_loop_(void *arg);
127 105
128 static FLAC__bool safe_decoder_init_(const char *filename, void **decoderp, decoder_funcs_t const ** fnsp); 106 static FLAC__bool safe_decoder_init_(const char *filename, void *decoder);
129 static void file_decoder_safe_decoder_finish_(void *decoder); 107 static void file_decoder_safe_decoder_finish_(void *decoder);
130 static void file_decoder_safe_decoder_delete_(void *decoder); 108 static void file_decoder_safe_decoder_delete_(void *decoder);
131 static FLAC__StreamDecoderWriteStatus write_callback_(const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); 109 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
132 static void metadata_callback_(const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data); 110 static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
133 static void error_callback_(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); 111 static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
134 112 static FLAC__bool file_decoder_is_eof(void *decoder);
135 static void init_decoder_func_tables(); 113
136 static decoder_t source_to_decoder_type (const char *source); 114 static decoder_t source_to_decoder_type (const char *source);
137 115
138 gchar *flac_fmts[] = { "flac", NULL }; 116 gchar *flac_fmts[] = { "flac", NULL };
139 117
140 InputPlugin flac_ip = 118 InputPlugin flac_ip =
183 161
184 #define BITRATE_HIST_SEGMENT_MSEC 500 162 #define BITRATE_HIST_SEGMENT_MSEC 500
185 /* 500ms * 50 = 25s should be enough */ 163 /* 500ms * 50 = 25s should be enough */
186 #define BITRATE_HIST_SIZE 50 164 #define BITRATE_HIST_SIZE 50
187 static unsigned bitrate_history_[BITRATE_HIST_SIZE]; 165 static unsigned bitrate_history_[BITRATE_HIST_SIZE];
188
189 /* A table of sets of decoder functions, indexed by decoder_t */
190 static const decoder_funcs_t* DECODER_FUNCS[NUM_DECODER_TYPES];
191
192 static decoder_funcs_t const * decoder_func_table_, * decoder_func_table2;
193 166
194 167
195 InputPlugin *get_iplugin_info() 168 InputPlugin *get_iplugin_info()
196 { 169 {
197 flac_ip.description = g_strdup_printf(_("FLAC Audio Plugin")); 170 flac_ip.description = g_strdup_printf(_("FLAC Audio Plugin"));
284 flac_cfg.stream.save_http_path = homedir(); 257 flac_cfg.stream.save_http_path = homedir();
285 } 258 }
286 bmp_cfg_db_get_bool(db, "flac", "stream.cast_title_streaming", &flac_cfg.stream.cast_title_streaming); 259 bmp_cfg_db_get_bool(db, "flac", "stream.cast_title_streaming", &flac_cfg.stream.cast_title_streaming);
287 bmp_cfg_db_get_bool(db, "flac", "stream.use_udp_channel", &flac_cfg.stream.use_udp_channel); 260 bmp_cfg_db_get_bool(db, "flac", "stream.use_udp_channel", &flac_cfg.stream.use_udp_channel);
288 261
289 init_decoder_func_tables(); 262 decoder_ = FLAC__seekable_stream_decoder_new();
290 decoder_func_table_ = DECODER_FUNCS [DECODER_FILE];
291 decoder_ = decoder_func_table_ -> new_decoder();
292 263
293 bmp_cfg_db_get_bool(db, NULL, "use_proxy", &flac_cfg.stream.use_proxy); 264 bmp_cfg_db_get_bool(db, NULL, "use_proxy", &flac_cfg.stream.use_proxy);
294 if(!bmp_cfg_db_get_string(db, NULL, "proxy_host", &flac_cfg.stream.proxy_host)) 265 if(!bmp_cfg_db_get_string(db, NULL, "proxy_host", &flac_cfg.stream.proxy_host))
295 flac_cfg.stream.proxy_host = NULL; 266 flac_cfg.stream.proxy_host = NULL;
296 bmp_cfg_db_get_string(db, NULL, "proxy_port", &tmp); 267 bmp_cfg_db_get_string(db, NULL, "proxy_port", &tmp);
350 file_info_.has_replaygain = false; 321 file_info_.has_replaygain = false;
351 322
352 if(decoder_ == 0) 323 if(decoder_ == 0)
353 return; 324 return;
354 325
355 if(!safe_decoder_init_(filename, &decoder_, &decoder_func_table_)) 326 if(!safe_decoder_init_(filename, decoder_))
356 return; 327 return;
357 328
358 if(file_info_.has_replaygain && flac_cfg.output.replaygain.enable) { 329 if(file_info_.has_replaygain && flac_cfg.output.replaygain.enable) {
359 if(flac_cfg.output.resolution.replaygain.bps_out == 8) { 330 if(flac_cfg.output.resolution.replaygain.bps_out == 8) {
360 file_info_.sample_format = FMT_U8; 331 file_info_.sample_format = FMT_U8;
365 file_info_.sample_format_bytes_per_sample = 2; 336 file_info_.sample_format_bytes_per_sample = 2;
366 } 337 }
367 else { 338 else {
368 /*@@@ 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); */ 339 /*@@@ 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); */
369 fprintf(stderr, "libxmms-flac: can't handle %d bit output\n", flac_cfg.output.resolution.replaygain.bps_out); 340 fprintf(stderr, "libxmms-flac: can't handle %d bit output\n", flac_cfg.output.resolution.replaygain.bps_out);
370 decoder_func_table_ -> safe_decoder_finish(decoder_); 341 file_decoder_safe_decoder_finish_(decoder_);
371 return; 342 return;
372 } 343 }
373 } 344 }
374 else { 345 else {
375 if(file_info_.bits_per_sample == 8) { 346 if(file_info_.bits_per_sample == 8) {
381 file_info_.sample_format_bytes_per_sample = 2; 352 file_info_.sample_format_bytes_per_sample = 2;
382 } 353 }
383 else { 354 else {
384 /*@@@ 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); */ 355 /*@@@ 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); */
385 fprintf(stderr, "libxmms-flac: can't handle %d bit output\n", file_info_.bits_per_sample); 356 fprintf(stderr, "libxmms-flac: can't handle %d bit output\n", file_info_.bits_per_sample);
386 decoder_func_table_ -> safe_decoder_finish(decoder_); 357 file_decoder_safe_decoder_finish_(decoder_);
387 return; 358 return;
388 } 359 }
389 } 360 }
390 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); 361 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);
391 file_info_.is_playing = true; 362 file_info_.is_playing = true;
392 363
393 if(flac_ip.output->open_audio(file_info_.sample_format, file_info_.sample_rate, file_info_.channels) == 0) { 364 if(flac_ip.output->open_audio(file_info_.sample_format, file_info_.sample_rate, file_info_.channels) == 0) {
394 audio_error_ = true; 365 audio_error_ = true;
395 decoder_func_table_ -> safe_decoder_finish(decoder_); 366 file_decoder_safe_decoder_finish_(decoder_);
396 return; 367 return;
397 } 368 }
398 369
399 file_info_.title = flac_format_song_title(filename); 370 file_info_.title = flac_format_song_title(filename);
400 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); 371 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);
411 if(file_info_.play_thread_open) { 382 if(file_info_.play_thread_open) {
412 file_info_.play_thread_open = false; 383 file_info_.play_thread_open = false;
413 g_thread_join(decode_thread_); 384 g_thread_join(decode_thread_);
414 } 385 }
415 flac_ip.output->close_audio(); 386 flac_ip.output->close_audio();
416 decoder_func_table_ -> safe_decoder_finish (decoder_); 387 file_decoder_safe_decoder_finish_(decoder_);
417 } 388 }
418 } 389 }
419 390
420 void FLAC_XMMS__pause(short p) 391 void FLAC_XMMS__pause(short p)
421 { 392 {
422 flac_ip.output->pause(p); 393 flac_ip.output->pause(p);
423 } 394 }
424 395
425 void FLAC_XMMS__seek(int time) 396 void FLAC_XMMS__seek(int time)
426 { 397 {
427 if (decoder_func_table_->seekable) { 398 file_info_.seek_to_in_sec = time;
428 file_info_.seek_to_in_sec = time; 399 file_info_.eof = false;
429 file_info_.eof = false; 400
430 401 while(file_info_.seek_to_in_sec != -1)
431 while(file_info_.seek_to_in_sec != -1) 402 xmms_usleep(10000);
432 xmms_usleep(10000);
433 }
434 } 403 }
435 404
436 int FLAC_XMMS__get_time() 405 int FLAC_XMMS__get_time()
437 { 406 {
438 if(audio_error_) 407 if(audio_error_)
472 if (flac_cfg.stream.proxy_pass) { 441 if (flac_cfg.stream.proxy_pass) {
473 g_free(flac_cfg.stream.proxy_pass); 442 g_free(flac_cfg.stream.proxy_pass);
474 flac_cfg.stream.proxy_pass = NULL; 443 flac_cfg.stream.proxy_pass = NULL;
475 } 444 }
476 445
477 decoder_func_table_ -> safe_decoder_delete(decoder_); 446 file_decoder_safe_decoder_delete_(decoder_);
478 decoder_ = 0; 447 decoder_ = 0;
479 } 448 }
480 449
481 void FLAC_XMMS__get_song_info(char *filename, char **title, int *length_in_msec) 450 void FLAC_XMMS__get_song_info(char *filename, char **title, int *length_in_msec)
482 { 451 {
523 if(!file_info_.eof) { 492 if(!file_info_.eof) {
524 while(sample_buffer_last_ - sample_buffer_first_ < SAMPLES_PER_WRITE) { 493 while(sample_buffer_last_ - sample_buffer_first_ < SAMPLES_PER_WRITE) {
525 unsigned s; 494 unsigned s;
526 495
527 s = sample_buffer_last_ - sample_buffer_first_; 496 s = sample_buffer_last_ - sample_buffer_first_;
528 if(decoder_func_table_ -> is_eof(decoder_)) { 497 if(file_decoder_is_eof(decoder_)) {
529 file_info_.eof = true; 498 file_info_.eof = true;
530 break; 499 break;
531 } 500 }
532 else if (!decoder_func_table_ -> process_single(decoder_)) { 501 else if (!FLAC__seekable_stream_decoder_process_single(decoder_)) {
533 /*@@@ this should probably be a dialog */ 502 /*@@@ this should probably be a dialog */
534 fprintf(stderr, "libxmms-flac: READ ERROR processing frame\n"); 503 fprintf(stderr, "libxmms-flac: READ ERROR processing frame\n");
535 file_info_.eof = true; 504 file_info_.eof = true;
536 break; 505 break;
537 } 506 }
538 blocksize = sample_buffer_last_ - sample_buffer_first_ - s; 507 blocksize = sample_buffer_last_ - sample_buffer_first_ - s;
539 decode_position_frame_last = decode_position_frame; 508 decode_position_frame_last = decode_position_frame;
540 if(!decoder_func_table_->seekable || !FLAC__seekable_stream_decoder_get_decode_position(decoder_, &decode_position_frame)) 509 if(!FLAC__seekable_stream_decoder_get_decode_position(decoder_, &decode_position_frame))
541 decode_position_frame = 0; 510 decode_position_frame = 0;
542 } 511 }
543 if(sample_buffer_last_ - sample_buffer_first_ > 0) { 512 if(sample_buffer_last_ - sample_buffer_first_ > 0) {
544 const unsigned n = min(sample_buffer_last_ - sample_buffer_first_, SAMPLES_PER_WRITE); 513 const unsigned n = min(sample_buffer_last_ - sample_buffer_first_, SAMPLES_PER_WRITE);
545 int bytes = n * file_info_.channels * file_info_.sample_format_bytes_per_sample; 514 int bytes = n * file_info_.channels * file_info_.sample_format_bytes_per_sample;
574 xmms_usleep(10000); 543 xmms_usleep(10000);
575 } 544 }
576 } 545 }
577 else 546 else
578 xmms_usleep(10000); 547 xmms_usleep(10000);
579 if(decoder_func_table_->seekable && file_info_.seek_to_in_sec != -1) { 548 if(file_info_.seek_to_in_sec != -1) {
580 const double distance = (double)file_info_.seek_to_in_sec * 1000.0 / (double)file_info_.length_in_msec; 549 const double distance = (double)file_info_.seek_to_in_sec * 1000.0 / (double)file_info_.length_in_msec;
581 unsigned target_sample = (unsigned)(distance * (double)file_info_.total_samples); 550 unsigned target_sample = (unsigned)(distance * (double)file_info_.total_samples);
582 if(FLAC__seekable_stream_decoder_seek_absolute(decoder_, (FLAC__uint64)target_sample)) { 551 if(FLAC__seekable_stream_decoder_seek_absolute(decoder_, (FLAC__uint64)target_sample)) {
583 flac_ip.output->flush(file_info_.seek_to_in_sec * 1000); 552 flac_ip.output->flush(file_info_.seek_to_in_sec * 1000);
584 bh_index_last_w = bh_index_last_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE; 553 bh_index_last_w = bh_index_last_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
598 flac_ip.set_info(file_info_.title, file_info_.length_in_msec, bitrate_history_[bh_index_o], file_info_.sample_rate, file_info_.channels); 567 flac_ip.set_info(file_info_.title, file_info_.length_in_msec, bitrate_history_[bh_index_o], file_info_.sample_rate, file_info_.channels);
599 } 568 }
600 } 569 }
601 } 570 }
602 571
603 decoder_func_table_ -> safe_decoder_finish(decoder_); 572 file_decoder_safe_decoder_finish_(decoder_);
604 573
605 /* are these two calls necessary? */ 574 /* are these two calls necessary? */
606 flac_ip.output->buffer_free(); 575 flac_ip.output->buffer_free();
607 flac_ip.output->buffer_free(); 576 flac_ip.output->buffer_free();
608 577
739 FLAC__seekable_stream_decoder_set_length_callback(decoder, file_decoder_length_callback); 708 FLAC__seekable_stream_decoder_set_length_callback(decoder, file_decoder_length_callback);
740 FLAC__seekable_stream_decoder_set_eof_callback(decoder, file_decoder_eof_callback); 709 FLAC__seekable_stream_decoder_set_eof_callback(decoder, file_decoder_eof_callback);
741 return FLAC__seekable_stream_decoder_init( (FLAC__SeekableStreamDecoder*) decoder) == FLAC__SEEKABLE_STREAM_DECODER_OK; 710 return FLAC__seekable_stream_decoder_init( (FLAC__SeekableStreamDecoder*) decoder) == FLAC__SEEKABLE_STREAM_DECODER_OK;
742 } 711 }
743 712
744 static const decoder_funcs_t FILE_DECODER_FUNCTIONS = { 713 static decoder_t source_to_decoder_type (const char *source)
745 true, 714 {
746 (void* (*) (void)) FLAC__seekable_stream_decoder_new, 715 /* NOTE: in Audacious, always use DECODER_FILE to pick files via VFS */
747 (FLAC__bool (*) (void *, const char*)) file_decoder_set_source, 716 return DECODER_FILE;
748 (FLAC__bool (*) (void *)) file_decoder_unset_source, 717 }
749 (FLAC__bool (*) (void *, FLAC__bool)) FLAC__seekable_stream_decoder_set_md5_checking, 718
750 (FLAC__bool (*) (void *)) FLAC__seekable_stream_decoder_set_metadata_ignore_all, 719 FLAC__bool safe_decoder_init_(const char *filename, void *decoder)
751 (FLAC__bool (*) (void *, FLAC__MetadataType)) FLAC__seekable_stream_decoder_set_metadata_respond, 720 {
752 (FLAC__bool (*) (void *, WriteCallback)) FLAC__seekable_stream_decoder_set_write_callback, 721 if(decoder == 0)
753 (FLAC__bool (*) (void *, MetadataCallback)) FLAC__seekable_stream_decoder_set_metadata_callback, 722 return false;
754 (FLAC__bool (*) (void *, ErrorCallback)) FLAC__seekable_stream_decoder_set_error_callback, 723
755 (FLAC__bool (*) (void *, void *)) FLAC__seekable_stream_decoder_set_client_data, 724 file_decoder_safe_decoder_finish_(decoder);
756 (FLAC__bool (*) (void *)) file_decoder_init, 725
757 (void (*) (void *)) file_decoder_safe_decoder_finish_, 726 file_decoder_set_source(decoder,filename);
758 (void (*) (void *)) file_decoder_safe_decoder_delete_, 727 FLAC__seekable_stream_decoder_set_md5_checking(decoder,false);
759 (FLAC__bool (*) (void *)) FLAC__seekable_stream_decoder_process_until_end_of_metadata, 728 FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder);
760 (FLAC__bool (*) (void *)) FLAC__seekable_stream_decoder_process_single, 729 FLAC__seekable_stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
761 file_decoder_is_eof 730 FLAC__seekable_stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
762 }; 731 FLAC__seekable_stream_decoder_set_write_callback(decoder, write_callback_);
763 732 FLAC__seekable_stream_decoder_set_metadata_callback(decoder, metadata_callback_);
764 /*********** HTTP decoder functions */ 733 FLAC__seekable_stream_decoder_set_error_callback(decoder, error_callback_);
765 734 FLAC__seekable_stream_decoder_set_client_data(decoder, &file_info_);
766 static gchar *url_ = NULL; 735
767 736 if ( !file_decoder_init(decoder) )
768 static FLAC__bool http_decoder_set_url (void *decoder, const char* url) 737 {
769 { 738 file_decoder_unset_source(decoder);
770 (void) decoder; 739 return false;
771 url_ = g_strdup (url); 740 }
741
742 if(!FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder))
743 {
744 file_decoder_unset_source(decoder);
745 return false;
746 }
747
772 return true; 748 return true;
773 } 749 }
774 750
775 static FLAC__bool http_decoder_unset_url (void *decoder) 751 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
776 {
777 (void) decoder;
778 if ( url_ != NULL )
779 {
780 g_free(url_);
781 url_ = NULL;
782 }
783 return true;
784 }
785
786 static FLAC__StreamDecoderReadStatus http_decoder_read_callback (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
787 {
788 (void) decoder;
789 (void) client_data;
790 *bytes = flac_http_read (buffer, *bytes);
791 return *bytes ? FLAC__STREAM_DECODER_READ_STATUS_CONTINUE : FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
792 }
793
794 static FLAC__bool http_decoder_init (void *decoder)
795 {
796 flac_http_open (url_, 0);
797 http_decoder_unset_url(decoder);
798 FLAC__stream_decoder_set_read_callback (decoder, http_decoder_read_callback);
799 return FLAC__stream_decoder_init( (FLAC__StreamDecoder*) decoder) == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;
800 }
801
802 static FLAC__bool http_decoder_set_md5_checking (void *decoder, FLAC__bool value)
803 {
804 return false;
805 }
806
807 static void http_decoder_safe_decoder_finish_(void *decoder)
808 {
809 if(decoder && FLAC__stream_decoder_get_state((FLAC__StreamDecoder *) decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) {
810 FLAC__stream_decoder_finish((FLAC__StreamDecoder *) decoder);
811 flac_http_close();
812 }
813 }
814
815 static void http_decoder_safe_decoder_delete_(void *decoder)
816 {
817 if(decoder) {
818 http_decoder_safe_decoder_finish_(decoder);
819 FLAC__stream_decoder_delete( (FLAC__StreamDecoder *) decoder);
820 }
821 }
822
823 static FLAC__bool http_decoder_is_eof(void *decoder)
824 {
825 return FLAC__stream_decoder_get_state((FLAC__StreamDecoder *) decoder) == FLAC__STREAM_DECODER_END_OF_STREAM;
826 }
827
828 static const decoder_funcs_t HTTP_DECODER_FUNCTIONS = {
829 false,
830 (void* (*) (void)) FLAC__stream_decoder_new,
831 (FLAC__bool (*) (void *, const char*)) http_decoder_set_url,
832 (FLAC__bool (*) (void *)) http_decoder_unset_url,
833 (FLAC__bool (*) (void *, FLAC__bool)) http_decoder_set_md5_checking,
834 (FLAC__bool (*) (void *)) FLAC__stream_decoder_set_metadata_ignore_all,
835 (FLAC__bool (*) (void *, FLAC__MetadataType)) FLAC__stream_decoder_set_metadata_respond,
836 (FLAC__bool (*) (void *, WriteCallback)) FLAC__stream_decoder_set_write_callback,
837 (FLAC__bool (*) (void *, MetadataCallback)) FLAC__stream_decoder_set_metadata_callback,
838 (FLAC__bool (*) (void *, ErrorCallback)) FLAC__stream_decoder_set_error_callback,
839 (FLAC__bool (*) (void *, void *)) FLAC__stream_decoder_set_client_data,
840 (FLAC__bool (*) (void *)) http_decoder_init,
841 (void (*) (void *)) http_decoder_safe_decoder_finish_,
842 (void (*) (void *)) http_decoder_safe_decoder_delete_,
843 (FLAC__bool (*) (void *)) FLAC__stream_decoder_process_until_end_of_metadata,
844 (FLAC__bool (*) (void *)) FLAC__stream_decoder_process_single,
845 http_decoder_is_eof
846 };
847
848 static decoder_funcs_t const *decoder_func_table_;
849
850 static void init_decoder_func_tables()
851 {
852 DECODER_FUNCS [DECODER_FILE] = & FILE_DECODER_FUNCTIONS;
853 DECODER_FUNCS [DECODER_HTTP] = & HTTP_DECODER_FUNCTIONS;
854 }
855
856 static decoder_t source_to_decoder_type (const char *source)
857 {
858 /* NOTE: in Audacious, always use DECODER_FILE to pick files via VFS;
859 http flac stream support is not used */
860 return DECODER_FILE;
861
862 /* return strncasecmp(source, "http://", 7) ? DECODER_FILE : DECODER_HTTP; */
863 }
864
865 static void change_decoder_if_needed (decoder_t new_decoder_type, void **decoderp, decoder_funcs_t const ** fntabp)
866 {
867 const decoder_funcs_t *new_fn_table = DECODER_FUNCS [new_decoder_type];
868 if (*fntabp != new_fn_table) {
869 (*fntabp)->safe_decoder_delete(*decoderp);
870 *fntabp = new_fn_table;
871 *decoderp = new_fn_table -> new_decoder();
872 }
873 }
874
875 FLAC__bool safe_decoder_init_(const char *filename, void **decoderp, decoder_funcs_t const ** fntabp)
876 {
877 if(decoderp == 0 || *decoderp == 0)
878 return false;
879
880 (*fntabp)->safe_decoder_finish(*decoderp);
881
882 change_decoder_if_needed(source_to_decoder_type(filename), decoderp, fntabp);
883
884 {
885 decoder_funcs_t const *fntab = *fntabp;
886 void *decoder = *decoderp;
887
888 decoder = *decoderp;
889 fntab = *fntabp;
890
891 fntab -> set_source(decoder, filename);
892 fntab -> set_md5_checking(decoder, false);
893 fntab -> set_metadata_ignore_all(decoder);
894 fntab -> set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
895 fntab -> set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
896 fntab -> set_write_callback(decoder, write_callback_);
897 fntab -> set_metadata_callback(decoder, metadata_callback_);
898 fntab -> set_error_callback(decoder, error_callback_);
899 fntab -> set_client_data(decoder, &file_info_);
900 if(!fntab -> decoder_init(decoder))
901 {
902 fntab -> unset_source(decoder);
903 return false;
904 }
905
906 if(!fntab -> process_until_end_of_metadata(decoder))
907 {
908 fntab -> unset_source(decoder);
909 return false;
910 }
911 }
912
913 return true;
914 }
915
916 FLAC__StreamDecoderWriteStatus write_callback_(const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
917 { 752 {
918 file_info_struct *file_info = (file_info_struct *)client_data; 753 file_info_struct *file_info = (file_info_struct *)client_data;
919 const unsigned channels = file_info->channels, wide_samples = frame->header.blocksize; 754 const unsigned channels = file_info->channels, wide_samples = frame->header.blocksize;
920 const unsigned bits_per_sample = file_info->bits_per_sample; 755 const unsigned bits_per_sample = file_info->bits_per_sample;
921 FLAC__byte *sample_buffer_start; 756 FLAC__byte *sample_buffer_start;
971 sample_buffer_last_ += wide_samples; 806 sample_buffer_last_ += wide_samples;
972 807
973 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; 808 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
974 } 809 }
975 810
976 void metadata_callback_(const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data) 811 void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
977 { 812 {
978 file_info_struct *file_info = (file_info_struct *)client_data; 813 file_info_struct *file_info = (file_info_struct *)client_data;
979 (void)decoder; 814 (void)decoder;
980 if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { 815 if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
981 FLAC__ASSERT(metadata->data.stream_info.total_samples < FLAC__U64L(0x100000000)); /* this plugin can only handle < 4 gigasamples */ 816 FLAC__ASSERT(metadata->data.stream_info.total_samples < FLAC__U64L(0x100000000)); /* this plugin can only handle < 4 gigasamples */
992 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); 827 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);
993 } 828 }
994 } 829 }
995 } 830 }
996 831
997 void error_callback_(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) 832 void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
998 { 833 {
999 file_info_struct *file_info = (file_info_struct *)client_data; 834 file_info_struct *file_info = (file_info_struct *)client_data;
1000 (void)decoder; 835 (void)decoder;
1001 if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) 836 if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC)
1002 file_info->abort_flag = true; 837 file_info->abort_flag = true;