playback.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:10k
源码类别:

Windows CE

开发平台:

C/C++

  1. /* in_flac - Winamp2 FLAC input plugin
  2.  * Copyright (C) 2000,2001,2002,2003,2004,2005  Josh Coalson
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  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
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  */
  18. #include <stdlib.h>
  19. #include <string.h> /* for memmove() */
  20. #include "playback.h"
  21. #include "share/grabbag.h"
  22. static FLAC__int32 reservoir_[FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS][FLAC__MAX_BLOCK_SIZE * 2/*for overflow*/];
  23. static FLAC__int32 *reservoir__[FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS] = { reservoir_[0], reservoir_[1] }; /*@@@ kind of a hard-coded hack */
  24. static unsigned wide_samples_in_reservoir_;
  25. static output_config_t cfg;     /* local copy */
  26. static unsigned bh_index_last_w, bh_index_last_o, written_time_last;
  27. static FLAC__int64 decode_position, decode_position_last;
  28. /*
  29.  *  callbacks
  30.  */
  31. static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
  32. {
  33. file_info_struct *file_info = (file_info_struct*)client_data;
  34. const unsigned channels = file_info->channels, wide_samples = frame->header.blocksize;
  35. unsigned channel;
  36. (void)decoder;
  37. if (file_info->abort_flag)
  38. return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
  39. for (channel = 0; channel < channels; channel++)
  40. memcpy(&reservoir_[channel][wide_samples_in_reservoir_], buffer[channel], sizeof(buffer[0][0]) * wide_samples);
  41. wide_samples_in_reservoir_ += wide_samples;
  42. return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
  43. }
  44. static void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
  45. {
  46. file_info_struct *file_info = (file_info_struct*)client_data;
  47. (void)decoder;
  48. if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO)
  49. {
  50. FLAC__ASSERT(metadata->data.stream_info.total_samples < 0x100000000); /* this plugin can only handle < 4 gigasamples */
  51. file_info->total_samples = (unsigned)(metadata->data.stream_info.total_samples&0xfffffffful);
  52. file_info->bits_per_sample = metadata->data.stream_info.bits_per_sample;
  53. file_info->channels = metadata->data.stream_info.channels;
  54. file_info->sample_rate = metadata->data.stream_info.sample_rate;
  55. if (file_info->bits_per_sample!=8 && file_info->bits_per_sample!=16 && file_info->bits_per_sample!=24)
  56. {
  57. FLAC_plugin__show_error("This plugin can only handle 8/16/24-bit samples.");
  58. file_info->abort_flag = true;
  59. return;
  60. }
  61. file_info->length_in_msec = (unsigned)((double)file_info->total_samples / (double)file_info->sample_rate * 1000.0 + 0.5);
  62. }
  63. else if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
  64. {
  65. double gain, peak;
  66. if (grabbag__replaygain_load_from_vorbiscomment(metadata, cfg.replaygain.album_mode, &gain, &peak))
  67. {
  68. file_info->has_replaygain = true;
  69. file_info->replay_scale = grabbag__replaygain_compute_scale_factor(peak, gain, (double)cfg.replaygain.preamp, !cfg.replaygain.hard_limit);
  70. }
  71. }
  72. }
  73. static void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
  74. {
  75. file_info_struct *file_info = (file_info_struct*)client_data;
  76. (void)decoder;
  77. if (cfg.misc.stop_err || status!=FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC)
  78. file_info->abort_flag = true;
  79. }
  80. /*
  81.  *  init/delete
  82.  */
  83. FLAC__bool FLAC_plugin__decoder_init(FLAC__FileDecoder *decoder, const char *filename, FLAC__int64 filesize, file_info_struct *file_info, output_config_t *config)
  84. {
  85. FLAC__ASSERT(decoder);
  86. FLAC_plugin__decoder_finish(decoder);
  87. /* init decoder */
  88. FLAC__file_decoder_set_md5_checking(decoder, false);
  89. FLAC__file_decoder_set_filename(decoder, filename);
  90. FLAC__file_decoder_set_metadata_ignore_all(decoder);
  91. FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
  92. FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
  93. FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback);
  94. FLAC__file_decoder_set_write_callback(decoder, write_callback);
  95. FLAC__file_decoder_set_error_callback(decoder, error_callback);
  96. FLAC__file_decoder_set_client_data(decoder, file_info);
  97. if (FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK)
  98. {
  99. FLAC_plugin__show_error("Error while initializing decoder (%s).", FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
  100. return false;
  101. }
  102. /* process */
  103. cfg = *config;
  104. wide_samples_in_reservoir_ = 0;
  105. file_info->is_playing = false;
  106. file_info->abort_flag = false;
  107. file_info->has_replaygain = false;
  108. if (!FLAC__file_decoder_process_until_end_of_metadata(decoder))
  109. {
  110. FLAC_plugin__show_error("Error while processing metadata (%s).", FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
  111. return false;
  112. }
  113. /* check results */
  114. if (file_info->abort_flag) return false;                /* metadata callback already popped up the error dialog */
  115. /* init replaygain */
  116. file_info->output_bits_per_sample = file_info->has_replaygain && cfg.replaygain.enable ?
  117. cfg.resolution.replaygain.bps_out :
  118. cfg.resolution.normal.dither_24_to_16 ? min(file_info->bits_per_sample, 16) : file_info->bits_per_sample;
  119. if (file_info->has_replaygain && cfg.replaygain.enable && cfg.resolution.replaygain.dither)
  120. FLAC__replaygain_synthesis__init_dither_context(&file_info->dither_context, file_info->bits_per_sample, cfg.resolution.replaygain.noise_shaping);
  121. /* more inits */
  122. file_info->eof = false;
  123. file_info->seek_to = -1;
  124. file_info->is_playing = true;
  125. file_info->average_bps = (unsigned)(filesize / (125.*file_info->total_samples/file_info->sample_rate));
  126. bh_index_last_w = 0;
  127. bh_index_last_o = BITRATE_HIST_SIZE;
  128. decode_position = 0;
  129. decode_position_last = 0;
  130. written_time_last = 0;
  131. return true;
  132. }
  133. void FLAC_plugin__decoder_finish(FLAC__FileDecoder *decoder)
  134. {
  135. if (decoder && FLAC__file_decoder_get_state(decoder)!=FLAC__FILE_DECODER_UNINITIALIZED)
  136. FLAC__file_decoder_finish(decoder);
  137. }
  138. void FLAC_plugin__decoder_delete(FLAC__FileDecoder *decoder)
  139. {
  140. if (decoder)
  141. {
  142. FLAC_plugin__decoder_finish(decoder);
  143. FLAC__file_decoder_delete(decoder);
  144. }
  145. }
  146. /*
  147.  *  decode
  148.  */
  149. int FLAC_plugin__seek(FLAC__FileDecoder *decoder, file_info_struct *file_info)
  150. {
  151. int pos;
  152. const FLAC__uint64 target_sample =
  153. (FLAC__uint64)file_info->total_samples*file_info->seek_to / file_info->length_in_msec;
  154. if (!FLAC__file_decoder_seek_absolute(decoder, target_sample))
  155. return -1;
  156. file_info->seek_to = -1;
  157. file_info->eof = false;
  158. wide_samples_in_reservoir_ = 0;
  159. pos = (int)(target_sample*1000 / file_info->sample_rate);
  160. bh_index_last_o = bh_index_last_w = (pos/BITRATE_HIST_SEGMENT_MSEC) % BITRATE_HIST_SIZE;
  161. if (!FLAC__file_decoder_get_decode_position(decoder, &decode_position))
  162. decode_position = 0;
  163. return pos;
  164. }
  165. unsigned FLAC_plugin__decode(FLAC__FileDecoder *decoder, file_info_struct *file_info, char *sample_buffer)
  166. {
  167. /* fill reservoir */
  168. while (wide_samples_in_reservoir_ < SAMPLES_PER_WRITE)
  169. {
  170. if (FLAC__file_decoder_get_state(decoder) == FLAC__FILE_DECODER_END_OF_FILE)
  171. {
  172. file_info->eof = true;
  173. break;
  174. }
  175. else if (!FLAC__file_decoder_process_single(decoder))
  176. {
  177. FLAC_plugin__show_error("Error while processing frame (%s).", FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
  178. file_info->eof = true;
  179. break;
  180. }
  181. if (!FLAC__file_decoder_get_decode_position(decoder, &decode_position))
  182. decode_position = 0;
  183. }
  184. /* output samples */
  185. if (wide_samples_in_reservoir_ > 0)
  186. {
  187. const unsigned n = min(wide_samples_in_reservoir_, SAMPLES_PER_WRITE);
  188. const unsigned channels = file_info->channels;
  189. unsigned i;
  190. int bytes;
  191. if (cfg.replaygain.enable && file_info->has_replaygain)
  192. {
  193. bytes = FLAC__replaygain_synthesis__apply_gain(
  194. sample_buffer,
  195. true, /* little_endian_data_out */
  196. file_info->output_bits_per_sample == 8, /* unsigned_data_out */
  197. reservoir__,
  198. n,
  199. channels,
  200. file_info->bits_per_sample,
  201. file_info->output_bits_per_sample,
  202. file_info->replay_scale,
  203. cfg.replaygain.hard_limit,
  204. cfg.resolution.replaygain.dither,
  205. &file_info->dither_context
  206. );
  207. }
  208. else
  209. {
  210. bytes = FLAC__plugin_common__pack_pcm_signed_little_endian(
  211. sample_buffer,
  212. reservoir__,
  213. n,
  214. channels,
  215. file_info->bits_per_sample,
  216. file_info->output_bits_per_sample
  217. );
  218. }
  219. wide_samples_in_reservoir_ -= n;
  220. for (i = 0; i < channels; i++)
  221. memmove(&reservoir_[i][0], &reservoir_[i][n], sizeof(reservoir_[0][0]) * wide_samples_in_reservoir_);
  222. return bytes;
  223. }
  224. else
  225. {
  226. file_info->eof = true;
  227. return 0;
  228. }
  229. }
  230. int FLAC_plugin__get_rate(unsigned written_time, unsigned output_time, file_info_struct *file_info)
  231. {
  232. static int bitrate_history_[BITRATE_HIST_SIZE];
  233. unsigned bh_index_w = (written_time/BITRATE_HIST_SEGMENT_MSEC) % BITRATE_HIST_SIZE;
  234. unsigned bh_index_o = (output_time/BITRATE_HIST_SEGMENT_MSEC) % BITRATE_HIST_SIZE;
  235. /* written bitrate */
  236. if (bh_index_w != bh_index_last_w)
  237. {
  238. bitrate_history_[(bh_index_w + BITRATE_HIST_SIZE-1)%BITRATE_HIST_SIZE] =
  239. decode_position>decode_position_last && written_time > written_time_last ?
  240. (unsigned)(8000*(decode_position - decode_position_last)/(written_time - written_time_last)) :
  241. file_info->average_bps;
  242. bh_index_last_w = bh_index_w;
  243. written_time_last = written_time;
  244. decode_position_last = decode_position;
  245. }
  246. /* output bitrate */
  247. if (bh_index_o!=bh_index_last_o && bh_index_o!=bh_index_last_w)
  248. {
  249. bh_index_last_o = bh_index_o;
  250. return bitrate_history_[bh_index_o];
  251. }
  252. return 0;
  253. }