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

Windows CE

开发平台:

C/C++

  1. /* libOggFLAC - Free Lossless Audio Codec + Ogg library
  2.  * Copyright (C) 2002,2003,2004,2005  Josh Coalson
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * - Redistributions of source code must retain the above copyright
  9.  * notice, this list of conditions and the following disclaimer.
  10.  *
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  * notice, this list of conditions and the following disclaimer in the
  13.  * documentation and/or other materials provided with the distribution.
  14.  *
  15.  * - Neither the name of the Xiph.org Foundation nor the names of its
  16.  * contributors may be used to endorse or promote products derived from
  17.  * this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20.  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22.  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
  23.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  25.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  26.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  27.  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  28.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30.  */
  31. #include <stdio.h>
  32. #include <stdlib.h> /* for calloc() */
  33. #include <string.h> /* for memcpy() */
  34. #include "FLAC/assert.h"
  35. #include "OggFLAC/seekable_stream_encoder.h"
  36. #include "protected/seekable_stream_encoder.h"
  37. #include "private/ogg_helper.h"
  38. #ifdef max
  39. #undef max
  40. #endif
  41. #define max(a,b) ((a)>(b)?(a):(b))
  42. /***********************************************************************
  43.  *
  44.  * Private class method prototypes
  45.  *
  46.  ***********************************************************************/
  47. /* unpublished debug routines */
  48. extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
  49. extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
  50. extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
  51. static void set_defaults_(OggFLAC__SeekableStreamEncoder *encoder);
  52. static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
  53. static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
  54. /***********************************************************************
  55.  *
  56.  * Private class data
  57.  *
  58.  ***********************************************************************/
  59. typedef struct OggFLAC__SeekableStreamEncoderPrivate {
  60. OggFLAC__SeekableStreamEncoderReadCallback read_callback;
  61. OggFLAC__SeekableStreamEncoderSeekCallback seek_callback;
  62. OggFLAC__SeekableStreamEncoderTellCallback tell_callback;
  63. OggFLAC__SeekableStreamEncoderWriteCallback write_callback;
  64. void *client_data;
  65. FLAC__StreamEncoder *FLAC_stream_encoder;
  66. FLAC__StreamMetadata_SeekTable *seek_table;
  67. /* internal vars (all the above are class settings) */
  68. unsigned first_seekpoint_to_check;
  69. FLAC__uint64 samples_written;
  70. } OggFLAC__SeekableStreamEncoderPrivate;
  71. /***********************************************************************
  72.  *
  73.  * Public static class data
  74.  *
  75.  ***********************************************************************/
  76. OggFLAC_API const char * const OggFLAC__SeekableStreamEncoderStateString[] = {
  77. "OggFLAC__SEEKABLE_STREAM_ENCODER_OK",
  78. "OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR",
  79. "OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR",
  80. "OggFLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
  81. "OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR",
  82. "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
  83. "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
  84. "OggFLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR",
  85. "OggFLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR",
  86. "OggFLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED",
  87. "OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK",
  88. "OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE",
  89. "OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED"
  90. };
  91. OggFLAC_API const char * const OggFLAC__SeekableStreamEncoderReadStatusString[] = {
  92. "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_CONTINUE",
  93. "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_END_OF_STREAM",
  94. "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_ABORT"
  95. };
  96. /***********************************************************************
  97.  *
  98.  * Class constructor/destructor
  99.  *
  100.  */
  101. OggFLAC_API OggFLAC__SeekableStreamEncoder *OggFLAC__seekable_stream_encoder_new()
  102. {
  103. OggFLAC__SeekableStreamEncoder *encoder;
  104. encoder = (OggFLAC__SeekableStreamEncoder*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoder));
  105. if(encoder == 0) {
  106. return 0;
  107. }
  108. encoder->protected_ = (OggFLAC__SeekableStreamEncoderProtected*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoderProtected));
  109. if(encoder->protected_ == 0) {
  110. free(encoder);
  111. return 0;
  112. }
  113. encoder->private_ = (OggFLAC__SeekableStreamEncoderPrivate*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoderPrivate));
  114. if(encoder->private_ == 0) {
  115. free(encoder->protected_);
  116. free(encoder);
  117. return 0;
  118. }
  119. encoder->private_->FLAC_stream_encoder = FLAC__stream_encoder_new();
  120. if(0 == encoder->private_->FLAC_stream_encoder) {
  121. free(encoder->private_);
  122. free(encoder->protected_);
  123. free(encoder);
  124. return 0;
  125. }
  126. set_defaults_(encoder);
  127. encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
  128. return encoder;
  129. }
  130. OggFLAC_API void OggFLAC__seekable_stream_encoder_delete(OggFLAC__SeekableStreamEncoder *encoder)
  131. {
  132. FLAC__ASSERT(0 != encoder);
  133. FLAC__ASSERT(0 != encoder->protected_);
  134. FLAC__ASSERT(0 != encoder->private_);
  135. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  136. (void)OggFLAC__seekable_stream_encoder_finish(encoder);
  137. FLAC__stream_encoder_delete(encoder->private_->FLAC_stream_encoder);
  138. free(encoder->private_);
  139. free(encoder->protected_);
  140. free(encoder);
  141. }
  142. /***********************************************************************
  143.  *
  144.  * Public class methods
  145.  *
  146.  ***********************************************************************/
  147. OggFLAC_API OggFLAC__SeekableStreamEncoderState OggFLAC__seekable_stream_encoder_init(OggFLAC__SeekableStreamEncoder *encoder)
  148. {
  149. FLAC__ASSERT(0 != encoder);
  150. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  151. return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED;
  152. if(0 == encoder->private_->seek_callback || 0 == encoder->private_->tell_callback || 0 == encoder->private_->write_callback)
  153. return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK;
  154. if(!OggFLAC__ogg_encoder_aspect_init(&encoder->protected_->ogg_encoder_aspect))
  155. return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
  156. if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table))
  157. return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE;
  158. /*
  159.  * These must be done before we init the stream encoder because that
  160.  * calls the write_callback, which uses these values.
  161.  */
  162. encoder->private_->first_seekpoint_to_check = 0;
  163. encoder->private_->samples_written = 0;
  164. encoder->protected_->streaminfo_offset = 0;
  165. encoder->protected_->seektable_offset = 0;
  166. encoder->protected_->audio_offset = 0;
  167. FLAC__stream_encoder_set_write_callback(encoder->private_->FLAC_stream_encoder, write_callback_);
  168. FLAC__stream_encoder_set_metadata_callback(encoder->private_->FLAC_stream_encoder, metadata_callback_);
  169. FLAC__stream_encoder_set_client_data(encoder->private_->FLAC_stream_encoder, encoder);
  170. if(FLAC__stream_encoder_init(encoder->private_->FLAC_stream_encoder) != FLAC__STREAM_ENCODER_OK)
  171. return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
  172. /*
  173.  * Initializing the stream encoder writes all the metadata, so we
  174.  * save the stream offset now.
  175.  */
  176. if(encoder->private_->tell_callback(encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
  177. return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
  178. return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OK;
  179. }
  180. OggFLAC_API void OggFLAC__seekable_stream_encoder_finish(OggFLAC__SeekableStreamEncoder *encoder)
  181. {
  182. FLAC__ASSERT(0 != encoder);
  183. FLAC__ASSERT(0 != encoder->private_);
  184. FLAC__ASSERT(0 != encoder->protected_);
  185. if(encoder->protected_->state == OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  186. return;
  187. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  188. FLAC__stream_encoder_finish(encoder->private_->FLAC_stream_encoder);
  189. OggFLAC__ogg_encoder_aspect_finish(&encoder->protected_->ogg_encoder_aspect);
  190. set_defaults_(encoder);
  191. encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
  192. }
  193. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_serial_number(OggFLAC__SeekableStreamEncoder *encoder, long value)
  194. {
  195. FLAC__ASSERT(0 != encoder);
  196. FLAC__ASSERT(0 != encoder->private_);
  197. FLAC__ASSERT(0 != encoder->protected_);
  198. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  199. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  200. return false;
  201. OggFLAC__ogg_encoder_aspect_set_serial_number(&encoder->protected_->ogg_encoder_aspect, value);
  202. return true;
  203. }
  204. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_verify(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  205. {
  206. FLAC__ASSERT(0 != encoder);
  207. FLAC__ASSERT(0 != encoder->private_);
  208. FLAC__ASSERT(0 != encoder->protected_);
  209. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  210. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  211. return false;
  212. return FLAC__stream_encoder_set_verify(encoder->private_->FLAC_stream_encoder, value);
  213. }
  214. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_streamable_subset(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  215. {
  216. FLAC__ASSERT(0 != encoder);
  217. FLAC__ASSERT(0 != encoder->private_);
  218. FLAC__ASSERT(0 != encoder->protected_);
  219. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  220. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  221. return false;
  222. return FLAC__stream_encoder_set_streamable_subset(encoder->private_->FLAC_stream_encoder, value);
  223. }
  224. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_mid_side_stereo(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  225. {
  226. FLAC__ASSERT(0 != encoder);
  227. FLAC__ASSERT(0 != encoder->private_);
  228. FLAC__ASSERT(0 != encoder->protected_);
  229. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  230. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  231. return false;
  232. return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->FLAC_stream_encoder, value);
  233. }
  234. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_loose_mid_side_stereo(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  235. {
  236. FLAC__ASSERT(0 != encoder);
  237. FLAC__ASSERT(0 != encoder->private_);
  238. FLAC__ASSERT(0 != encoder->protected_);
  239. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  240. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  241. return false;
  242. return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->FLAC_stream_encoder, value);
  243. }
  244. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_channels(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
  245. {
  246. FLAC__ASSERT(0 != encoder);
  247. FLAC__ASSERT(0 != encoder->private_);
  248. FLAC__ASSERT(0 != encoder->protected_);
  249. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  250. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  251. return false;
  252. return FLAC__stream_encoder_set_channels(encoder->private_->FLAC_stream_encoder, value);
  253. }
  254. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_bits_per_sample(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
  255. {
  256. FLAC__ASSERT(0 != encoder);
  257. FLAC__ASSERT(0 != encoder->private_);
  258. FLAC__ASSERT(0 != encoder->protected_);
  259. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  260. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  261. return false;
  262. return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->FLAC_stream_encoder, value);
  263. }
  264. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_sample_rate(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
  265. {
  266. FLAC__ASSERT(0 != encoder);
  267. FLAC__ASSERT(0 != encoder->private_);
  268. FLAC__ASSERT(0 != encoder->protected_);
  269. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  270. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  271. return false;
  272. return FLAC__stream_encoder_set_sample_rate(encoder->private_->FLAC_stream_encoder, value);
  273. }
  274. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_blocksize(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
  275. {
  276. FLAC__ASSERT(0 != encoder);
  277. FLAC__ASSERT(0 != encoder->private_);
  278. FLAC__ASSERT(0 != encoder->protected_);
  279. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  280. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  281. return false;
  282. return FLAC__stream_encoder_set_blocksize(encoder->private_->FLAC_stream_encoder, value);
  283. }
  284. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_max_lpc_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
  285. {
  286. FLAC__ASSERT(0 != encoder);
  287. FLAC__ASSERT(0 != encoder->private_);
  288. FLAC__ASSERT(0 != encoder->protected_);
  289. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  290. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  291. return false;
  292. return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->FLAC_stream_encoder, value);
  293. }
  294. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_qlp_coeff_precision(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
  295. {
  296. FLAC__ASSERT(0 != encoder);
  297. FLAC__ASSERT(0 != encoder->private_);
  298. FLAC__ASSERT(0 != encoder->protected_);
  299. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  300. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  301. return false;
  302. return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->FLAC_stream_encoder, value);
  303. }
  304. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  305. {
  306. FLAC__ASSERT(0 != encoder);
  307. FLAC__ASSERT(0 != encoder->private_);
  308. FLAC__ASSERT(0 != encoder->protected_);
  309. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  310. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  311. return false;
  312. return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->FLAC_stream_encoder, value);
  313. }
  314. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_escape_coding(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  315. {
  316. FLAC__ASSERT(0 != encoder);
  317. FLAC__ASSERT(0 != encoder->private_);
  318. FLAC__ASSERT(0 != encoder->protected_);
  319. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  320. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  321. return false;
  322. return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->FLAC_stream_encoder, value);
  323. }
  324. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_exhaustive_model_search(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  325. {
  326. FLAC__ASSERT(0 != encoder);
  327. FLAC__ASSERT(0 != encoder->private_);
  328. FLAC__ASSERT(0 != encoder->protected_);
  329. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  330. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  331. return false;
  332. return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->FLAC_stream_encoder, value);
  333. }
  334. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_min_residual_partition_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
  335. {
  336. FLAC__ASSERT(0 != encoder);
  337. FLAC__ASSERT(0 != encoder->private_);
  338. FLAC__ASSERT(0 != encoder->protected_);
  339. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  340. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  341. return false;
  342. return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->FLAC_stream_encoder, value);
  343. }
  344. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_max_residual_partition_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
  345. {
  346. FLAC__ASSERT(0 != encoder);
  347. FLAC__ASSERT(0 != encoder->private_);
  348. FLAC__ASSERT(0 != encoder->protected_);
  349. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  350. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  351. return false;
  352. return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->FLAC_stream_encoder, value);
  353. }
  354. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_rice_parameter_search_dist(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
  355. {
  356. FLAC__ASSERT(0 != encoder);
  357. FLAC__ASSERT(0 != encoder->private_);
  358. FLAC__ASSERT(0 != encoder->protected_);
  359. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  360. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  361. return false;
  362. return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->FLAC_stream_encoder, value);
  363. }
  364. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_total_samples_estimate(OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value)
  365. {
  366. FLAC__ASSERT(0 != encoder);
  367. FLAC__ASSERT(0 != encoder->private_);
  368. FLAC__ASSERT(0 != encoder->protected_);
  369. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  370. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  371. return false;
  372. return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->FLAC_stream_encoder, value);
  373. }
  374. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_metadata(OggFLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
  375. {
  376. FLAC__ASSERT(0 != encoder);
  377. FLAC__ASSERT(0 != encoder->private_);
  378. FLAC__ASSERT(0 != encoder->protected_);
  379. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  380. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  381. return false;
  382. /* reorder metadata if necessary to ensure that any VORBIS_COMMENT is the first, according to the mapping spec */
  383. if(0 != metadata && num_blocks > 1) {
  384. unsigned i;
  385. for(i = 1; i < num_blocks; i++) {
  386. if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
  387. FLAC__StreamMetadata *vc = metadata[i];
  388. for( ; i > 0; i--)
  389. metadata[i] = metadata[i-1];
  390. metadata[0] = vc;
  391. break;
  392. }
  393. }
  394. }
  395. if(0 != metadata && num_blocks > 0) {
  396. unsigned i;
  397. for(i = 0; i < num_blocks; i++) {
  398. /* keep track of any SEEKTABLE block */
  399. if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
  400. encoder->private_->seek_table = &metadata[i]->data.seek_table;
  401. break; /* take only the first one */
  402. }
  403. }
  404. }
  405. if(!OggFLAC__ogg_encoder_aspect_set_num_metadata(&encoder->protected_->ogg_encoder_aspect, num_blocks))
  406. return false;
  407. return FLAC__stream_encoder_set_metadata(encoder->private_->FLAC_stream_encoder, metadata, num_blocks);
  408. }
  409. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_read_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderReadCallback value)
  410. {
  411. FLAC__ASSERT(0 != encoder);
  412. FLAC__ASSERT(0 != encoder->private_);
  413. FLAC__ASSERT(0 != encoder->protected_);
  414. FLAC__ASSERT(0 != value);
  415. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  416. return false;
  417. encoder->private_->read_callback = value;
  418. return true;
  419. }
  420. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_seek_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderSeekCallback value)
  421. {
  422. FLAC__ASSERT(0 != encoder);
  423. FLAC__ASSERT(0 != encoder->private_);
  424. FLAC__ASSERT(0 != encoder->protected_);
  425. FLAC__ASSERT(0 != value);
  426. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  427. return false;
  428. encoder->private_->seek_callback = value;
  429. return true;
  430. }
  431. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_tell_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderTellCallback value)
  432. {
  433. FLAC__ASSERT(0 != encoder);
  434. FLAC__ASSERT(0 != encoder->private_);
  435. FLAC__ASSERT(0 != encoder->protected_);
  436. FLAC__ASSERT(0 != value);
  437. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  438. return false;
  439. encoder->private_->tell_callback = value;
  440. return true;
  441. }
  442. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_write_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderWriteCallback value)
  443. {
  444. FLAC__ASSERT(0 != encoder);
  445. FLAC__ASSERT(0 != encoder->private_);
  446. FLAC__ASSERT(0 != encoder->protected_);
  447. FLAC__ASSERT(0 != value);
  448. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  449. return false;
  450. encoder->private_->write_callback = value;
  451. return true;
  452. }
  453. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_client_data(OggFLAC__SeekableStreamEncoder *encoder, void *value)
  454. {
  455. FLAC__ASSERT(0 != encoder);
  456. FLAC__ASSERT(0 != encoder->private_);
  457. FLAC__ASSERT(0 != encoder->protected_);
  458. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  459. return false;
  460. encoder->private_->client_data = value;
  461. return true;
  462. }
  463. /*
  464.  * These three functions are not static, but not publically exposed in
  465.  * include/FLAC/ either.  They are used by the test suite.
  466.  */
  467. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_disable_constant_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  468. {
  469. FLAC__ASSERT(0 != encoder);
  470. FLAC__ASSERT(0 != encoder->private_);
  471. FLAC__ASSERT(0 != encoder->protected_);
  472. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  473. return false;
  474. return FLAC__stream_encoder_disable_constant_subframes(encoder->private_->FLAC_stream_encoder, value);
  475. }
  476. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_disable_fixed_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  477. {
  478. FLAC__ASSERT(0 != encoder);
  479. FLAC__ASSERT(0 != encoder->private_);
  480. FLAC__ASSERT(0 != encoder->protected_);
  481. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  482. return false;
  483. return FLAC__stream_encoder_disable_fixed_subframes(encoder->private_->FLAC_stream_encoder, value);
  484. }
  485. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_disable_verbatim_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  486. {
  487. FLAC__ASSERT(0 != encoder);
  488. FLAC__ASSERT(0 != encoder->private_);
  489. FLAC__ASSERT(0 != encoder->protected_);
  490. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  491. return false;
  492. return FLAC__stream_encoder_disable_verbatim_subframes(encoder->private_->FLAC_stream_encoder, value);
  493. }
  494. OggFLAC_API OggFLAC__SeekableStreamEncoderState OggFLAC__seekable_stream_encoder_get_state(const OggFLAC__SeekableStreamEncoder *encoder)
  495. {
  496. FLAC__ASSERT(0 != encoder);
  497. FLAC__ASSERT(0 != encoder->private_);
  498. FLAC__ASSERT(0 != encoder->protected_);
  499. return encoder->protected_->state;
  500. }
  501. OggFLAC_API FLAC__StreamEncoderState OggFLAC__seekable_stream_encoder_get_FLAC_stream_encoder_state(const OggFLAC__SeekableStreamEncoder *encoder)
  502. {
  503. FLAC__ASSERT(0 != encoder);
  504. FLAC__ASSERT(0 != encoder->private_);
  505. FLAC__ASSERT(0 != encoder->protected_);
  506. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  507. return FLAC__stream_encoder_get_state(encoder->private_->FLAC_stream_encoder);
  508. }
  509. OggFLAC_API FLAC__StreamDecoderState OggFLAC__seekable_stream_encoder_get_verify_decoder_state(const OggFLAC__SeekableStreamEncoder *encoder)
  510. {
  511. FLAC__ASSERT(0 != encoder);
  512. FLAC__ASSERT(0 != encoder->private_);
  513. FLAC__ASSERT(0 != encoder->protected_);
  514. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  515. return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->FLAC_stream_encoder);
  516. }
  517. OggFLAC_API const char *OggFLAC__seekable_stream_encoder_get_resolved_state_string(const OggFLAC__SeekableStreamEncoder *encoder)
  518. {
  519. FLAC__ASSERT(0 != encoder);
  520. FLAC__ASSERT(0 != encoder->private_);
  521. FLAC__ASSERT(0 != encoder->protected_);
  522. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  523. if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR)
  524. return OggFLAC__SeekableStreamEncoderStateString[encoder->protected_->state];
  525. else
  526. return FLAC__stream_encoder_get_resolved_state_string(encoder->private_->FLAC_stream_encoder);
  527. }
  528. OggFLAC_API void OggFLAC__seekable_stream_encoder_get_verify_decoder_error_stats(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
  529. {
  530. FLAC__ASSERT(0 != encoder);
  531. FLAC__ASSERT(0 != encoder->private_);
  532. FLAC__ASSERT(0 != encoder->protected_);
  533. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  534. FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->FLAC_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
  535. }
  536. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_verify(const OggFLAC__SeekableStreamEncoder *encoder)
  537. {
  538. FLAC__ASSERT(0 != encoder);
  539. FLAC__ASSERT(0 != encoder->private_);
  540. FLAC__ASSERT(0 != encoder->protected_);
  541. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  542. return FLAC__stream_encoder_get_verify(encoder->private_->FLAC_stream_encoder);
  543. }
  544. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_streamable_subset(const OggFLAC__SeekableStreamEncoder *encoder)
  545. {
  546. FLAC__ASSERT(0 != encoder);
  547. FLAC__ASSERT(0 != encoder->private_);
  548. FLAC__ASSERT(0 != encoder->protected_);
  549. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  550. return FLAC__stream_encoder_get_streamable_subset(encoder->private_->FLAC_stream_encoder);
  551. }
  552. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_mid_side_stereo(const OggFLAC__SeekableStreamEncoder *encoder)
  553. {
  554. FLAC__ASSERT(0 != encoder);
  555. FLAC__ASSERT(0 != encoder->private_);
  556. FLAC__ASSERT(0 != encoder->protected_);
  557. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  558. return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->FLAC_stream_encoder);
  559. }
  560. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const OggFLAC__SeekableStreamEncoder *encoder)
  561. {
  562. FLAC__ASSERT(0 != encoder);
  563. FLAC__ASSERT(0 != encoder->private_);
  564. FLAC__ASSERT(0 != encoder->protected_);
  565. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  566. return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->FLAC_stream_encoder);
  567. }
  568. OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_channels(const OggFLAC__SeekableStreamEncoder *encoder)
  569. {
  570. FLAC__ASSERT(0 != encoder);
  571. FLAC__ASSERT(0 != encoder->private_);
  572. FLAC__ASSERT(0 != encoder->protected_);
  573. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  574. return FLAC__stream_encoder_get_channels(encoder->private_->FLAC_stream_encoder);
  575. }
  576. OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_bits_per_sample(const OggFLAC__SeekableStreamEncoder *encoder)
  577. {
  578. FLAC__ASSERT(0 != encoder);
  579. FLAC__ASSERT(0 != encoder->private_);
  580. FLAC__ASSERT(0 != encoder->protected_);
  581. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  582. return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->FLAC_stream_encoder);
  583. }
  584. OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_sample_rate(const OggFLAC__SeekableStreamEncoder *encoder)
  585. {
  586. FLAC__ASSERT(0 != encoder);
  587. FLAC__ASSERT(0 != encoder->private_);
  588. FLAC__ASSERT(0 != encoder->protected_);
  589. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  590. return FLAC__stream_encoder_get_sample_rate(encoder->private_->FLAC_stream_encoder);
  591. }
  592. OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_blocksize(const OggFLAC__SeekableStreamEncoder *encoder)
  593. {
  594. FLAC__ASSERT(0 != encoder);
  595. FLAC__ASSERT(0 != encoder->private_);
  596. FLAC__ASSERT(0 != encoder->protected_);
  597. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  598. return FLAC__stream_encoder_get_blocksize(encoder->private_->FLAC_stream_encoder);
  599. }
  600. OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_max_lpc_order(const OggFLAC__SeekableStreamEncoder *encoder)
  601. {
  602. FLAC__ASSERT(0 != encoder);
  603. FLAC__ASSERT(0 != encoder->private_);
  604. FLAC__ASSERT(0 != encoder->protected_);
  605. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  606. return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->FLAC_stream_encoder);
  607. }
  608. OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_qlp_coeff_precision(const OggFLAC__SeekableStreamEncoder *encoder)
  609. {
  610. FLAC__ASSERT(0 != encoder);
  611. FLAC__ASSERT(0 != encoder->private_);
  612. FLAC__ASSERT(0 != encoder->protected_);
  613. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  614. return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->FLAC_stream_encoder);
  615. }
  616. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const OggFLAC__SeekableStreamEncoder *encoder)
  617. {
  618. FLAC__ASSERT(0 != encoder);
  619. FLAC__ASSERT(0 != encoder->private_);
  620. FLAC__ASSERT(0 != encoder->protected_);
  621. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  622. return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->FLAC_stream_encoder);
  623. }
  624. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_escape_coding(const OggFLAC__SeekableStreamEncoder *encoder)
  625. {
  626. FLAC__ASSERT(0 != encoder);
  627. FLAC__ASSERT(0 != encoder->private_);
  628. FLAC__ASSERT(0 != encoder->protected_);
  629. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  630. return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->FLAC_stream_encoder);
  631. }
  632. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const OggFLAC__SeekableStreamEncoder *encoder)
  633. {
  634. FLAC__ASSERT(0 != encoder);
  635. FLAC__ASSERT(0 != encoder->private_);
  636. FLAC__ASSERT(0 != encoder->protected_);
  637. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  638. return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->FLAC_stream_encoder);
  639. }
  640. OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_min_residual_partition_order(const OggFLAC__SeekableStreamEncoder *encoder)
  641. {
  642. FLAC__ASSERT(0 != encoder);
  643. FLAC__ASSERT(0 != encoder->private_);
  644. FLAC__ASSERT(0 != encoder->protected_);
  645. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  646. return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->FLAC_stream_encoder);
  647. }
  648. OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_max_residual_partition_order(const OggFLAC__SeekableStreamEncoder *encoder)
  649. {
  650. FLAC__ASSERT(0 != encoder);
  651. FLAC__ASSERT(0 != encoder->private_);
  652. FLAC__ASSERT(0 != encoder->protected_);
  653. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  654. return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->FLAC_stream_encoder);
  655. }
  656. OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const OggFLAC__SeekableStreamEncoder *encoder)
  657. {
  658. FLAC__ASSERT(0 != encoder);
  659. FLAC__ASSERT(0 != encoder->private_);
  660. FLAC__ASSERT(0 != encoder->protected_);
  661. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  662. return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->FLAC_stream_encoder);
  663. }
  664. OggFLAC_API FLAC__uint64 OggFLAC__seekable_stream_encoder_get_total_samples_estimate(const OggFLAC__SeekableStreamEncoder *encoder)
  665. {
  666. FLAC__ASSERT(0 != encoder);
  667. FLAC__ASSERT(0 != encoder->private_);
  668. FLAC__ASSERT(0 != encoder->protected_);
  669. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  670. return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->FLAC_stream_encoder);
  671. }
  672. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_process(OggFLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
  673. {
  674. FLAC__ASSERT(0 != encoder);
  675. FLAC__ASSERT(0 != encoder->private_);
  676. FLAC__ASSERT(0 != encoder->protected_);
  677. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  678. if(!FLAC__stream_encoder_process(encoder->private_->FLAC_stream_encoder, buffer, samples)) {
  679. encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
  680. return false;
  681. }
  682. else
  683. return true;
  684. }
  685. OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_process_interleaved(OggFLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
  686. {
  687. FLAC__ASSERT(0 != encoder);
  688. FLAC__ASSERT(0 != encoder->private_);
  689. FLAC__ASSERT(0 != encoder->protected_);
  690. FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
  691. if(!FLAC__stream_encoder_process_interleaved(encoder->private_->FLAC_stream_encoder, buffer, samples)) {
  692. encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
  693. return false;
  694. }
  695. else
  696. return true;
  697. }
  698. /***********************************************************************
  699.  *
  700.  * Private class methods
  701.  *
  702.  ***********************************************************************/
  703. void set_defaults_(OggFLAC__SeekableStreamEncoder *encoder)
  704. {
  705. FLAC__ASSERT(0 != encoder);
  706. FLAC__ASSERT(0 != encoder->private_);
  707. FLAC__ASSERT(0 != encoder->protected_);
  708. encoder->private_->seek_callback = 0;
  709. encoder->private_->tell_callback = 0;
  710. encoder->private_->write_callback = 0;
  711. encoder->private_->client_data = 0;
  712. encoder->private_->seek_table = 0;
  713. OggFLAC__ogg_encoder_aspect_set_defaults(&encoder->protected_->ogg_encoder_aspect);
  714. }
  715. FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
  716. {
  717. OggFLAC__SeekableStreamEncoder *encoder = (OggFLAC__SeekableStreamEncoder*)client_data;
  718. FLAC__StreamEncoderWriteStatus status;
  719. FLAC__uint64 output_position;
  720. (void)unused; /* silence compiler warning about unused parameter */
  721. FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused);
  722. if(encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
  723. return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
  724. /*
  725.  * Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets.
  726.  */
  727. if(samples == 0) {
  728. FLAC__MetadataType type = (buffer[0] & 0x7f);
  729. if(type == FLAC__METADATA_TYPE_STREAMINFO)
  730. encoder->protected_->streaminfo_offset = output_position;
  731. else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0)
  732. encoder->protected_->seektable_offset = output_position;
  733. }
  734. /*
  735.  * Mark the current seek point if hit (if audio_offset == 0 that
  736.  * means we're still writing metadata and haven't hit the first
  737.  * frame yet)
  738.  */
  739. if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) {
  740. const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder->private_->FLAC_stream_encoder);
  741. const FLAC__uint64 frame_first_sample = encoder->private_->samples_written;
  742. const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
  743. FLAC__uint64 test_sample;
  744. unsigned i;
  745. for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) {
  746. test_sample = encoder->private_->seek_table->points[i].sample_number;
  747. if(test_sample > frame_last_sample) {
  748. break;
  749. }
  750. else if(test_sample >= frame_first_sample) {
  751. encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
  752. encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset;
  753. encoder->private_->seek_table->points[i].frame_samples = blocksize;
  754. encoder->private_->first_seekpoint_to_check++;
  755. /* DO NOT: "break;" and here's why:
  756.  * The seektable template may contain more than one target
  757.  * sample for any given frame; we will keep looping, generating
  758.  * duplicate seekpoints for them, and we'll clean it up later,
  759.  * just before writing the seektable back to the metadata.
  760.  */
  761. }
  762. else {
  763. encoder->private_->first_seekpoint_to_check++;
  764. }
  765. }
  766. }
  767. status = OggFLAC__ogg_encoder_aspect_write_callback_wrapper(&encoder->protected_->ogg_encoder_aspect, FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->FLAC_stream_encoder), buffer, bytes, samples, current_frame, (OggFLAC__OggEncoderAspectWriteCallbackProxy)encoder->private_->write_callback, encoder, encoder->private_->client_data);
  768. if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
  769. encoder->private_->samples_written += samples;
  770. }
  771. else
  772. encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
  773. return status;
  774. }
  775. void metadata_callback_(const FLAC__StreamEncoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
  776. {
  777. OggFLAC__SeekableStreamEncoder *encoder = (OggFLAC__SeekableStreamEncoder*)client_data;
  778. FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
  779. const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
  780. const unsigned min_framesize = metadata->data.stream_info.min_framesize;
  781. const unsigned max_framesize = metadata->data.stream_info.max_framesize;
  782. ogg_page page;
  783. FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
  784. /* We get called by the stream encoder when the encoding process
  785.  * has finished so that we can update the STREAMINFO and SEEKTABLE
  786.  * blocks.
  787.  */
  788. (void)unused; /* silence compiler warning about unused parameter */
  789. FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused);
  790. /*@@@ reopen callback here?  The docs currently require user to open files in update mode from the start */
  791. /* All this is based on intimate knowledge of the stream header
  792.  * layout, but a change to the header format that would break this
  793.  * would also break all streams encoded in the previous format.
  794.  */
  795. /*
  796.  * Write STREAMINFO stats
  797.  */
  798. simple_ogg_page__init(&page);
  799. if(!simple_ogg_page__get_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
  800. simple_ogg_page__clear(&page);
  801. return; /* state already set */
  802. }
  803. /*
  804.  * MD5 signature
  805.  */
  806. {
  807. const unsigned md5_offset =
  808. FLAC__STREAM_METADATA_HEADER_LENGTH +
  809. (
  810. FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
  811. FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
  812. FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
  813. FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
  814. FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
  815. FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
  816. FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
  817. FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
  818. ) / 8;
  819. if(md5_offset + 16 > (unsigned)page.body_len) {
  820. encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
  821. simple_ogg_page__clear(&page);
  822. return;
  823. }
  824. memcpy(page.body + md5_offset, metadata->data.stream_info.md5sum, 16);
  825. }
  826. /*
  827.  * total samples
  828.  */
  829. {
  830. const unsigned total_samples_byte_offset =
  831. FLAC__STREAM_METADATA_HEADER_LENGTH +
  832. (
  833. FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
  834. FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
  835. FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
  836. FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
  837. FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
  838. FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
  839. FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
  840. - 4
  841. ) / 8;
  842. if(total_samples_byte_offset + 5 > (unsigned)page.body_len) {
  843. encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
  844. simple_ogg_page__clear(&page);
  845. return;
  846. }
  847. b[0] = (FLAC__byte)page.body[total_samples_byte_offset] & 0xF0;
  848. b[0] |= (FLAC__byte)((samples >> 32) & 0x0F);
  849. b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
  850. b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
  851. b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
  852. b[4] = (FLAC__byte)(samples & 0xFF);
  853. memcpy(page.body + total_samples_byte_offset, b, 5);
  854. }
  855. /*
  856.  * min/max framesize
  857.  */
  858. {
  859. const unsigned min_framesize_offset =
  860. FLAC__STREAM_METADATA_HEADER_LENGTH +
  861. (
  862. FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
  863. FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
  864. ) / 8;
  865. if(min_framesize_offset + 6 > (unsigned)page.body_len) {
  866. encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
  867. simple_ogg_page__clear(&page);
  868. return;
  869. }
  870. b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
  871. b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
  872. b[2] = (FLAC__byte)(min_framesize & 0xFF);
  873. b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
  874. b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
  875. b[5] = (FLAC__byte)(max_framesize & 0xFF);
  876. memcpy(page.body + min_framesize_offset, b, 6);
  877. }
  878. if(!simple_ogg_page__set_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
  879. simple_ogg_page__clear(&page);
  880. return; /* state already set */
  881. }
  882. simple_ogg_page__clear(&page);
  883. /*
  884.  * Write seektable
  885.  */
  886. if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
  887. unsigned i;
  888. FLAC__byte *p;
  889. FLAC__format_seektable_sort(encoder->private_->seek_table);
  890. FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
  891. simple_ogg_page__init(&page);
  892. if(!simple_ogg_page__get_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
  893. simple_ogg_page__clear(&page);
  894. return; /* state already set */
  895. }
  896. if(FLAC__STREAM_METADATA_HEADER_LENGTH + (18*encoder->private_->seek_table->num_points) > (unsigned)page.body_len) {
  897. encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
  898. simple_ogg_page__clear(&page);
  899. return;
  900. }
  901. for(i = 0, p = page.body + FLAC__STREAM_METADATA_HEADER_LENGTH; i < encoder->private_->seek_table->num_points; i++, p += 18) {
  902. FLAC__uint64 xx;
  903. unsigned x;
  904. xx = encoder->private_->seek_table->points[i].sample_number;
  905. b[7] = (FLAC__byte)xx; xx >>= 8;
  906. b[6] = (FLAC__byte)xx; xx >>= 8;
  907. b[5] = (FLAC__byte)xx; xx >>= 8;
  908. b[4] = (FLAC__byte)xx; xx >>= 8;
  909. b[3] = (FLAC__byte)xx; xx >>= 8;
  910. b[2] = (FLAC__byte)xx; xx >>= 8;
  911. b[1] = (FLAC__byte)xx; xx >>= 8;
  912. b[0] = (FLAC__byte)xx; xx >>= 8;
  913. xx = encoder->private_->seek_table->points[i].stream_offset;
  914. b[15] = (FLAC__byte)xx; xx >>= 8;
  915. b[14] = (FLAC__byte)xx; xx >>= 8;
  916. b[13] = (FLAC__byte)xx; xx >>= 8;
  917. b[12] = (FLAC__byte)xx; xx >>= 8;
  918. b[11] = (FLAC__byte)xx; xx >>= 8;
  919. b[10] = (FLAC__byte)xx; xx >>= 8;
  920. b[9] = (FLAC__byte)xx; xx >>= 8;
  921. b[8] = (FLAC__byte)xx; xx >>= 8;
  922. x = encoder->private_->seek_table->points[i].frame_samples;
  923. b[17] = (FLAC__byte)x; x >>= 8;
  924. b[16] = (FLAC__byte)x; x >>= 8;
  925. if(encoder->private_->write_callback(encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
  926. encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
  927. simple_ogg_page__clear(&page);
  928. return;
  929. }
  930. memcpy(p, b, 18);
  931. }
  932. if(!simple_ogg_page__set_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
  933. simple_ogg_page__clear(&page);
  934. return; /* state already set */
  935. }
  936. simple_ogg_page__clear(&page);
  937. }
  938. }