seekable_stream_encoder.c
Upload User: wstnjxml
Upload Date: 2014-04-03
Package Size: 7248k
Code Size: 38k
Category:

Windows CE

Development Platform:

C/C++

  1. /* libFLAC - Free Lossless Audio Codec 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 "protected/seekable_stream_encoder.h"
  36. #ifdef max
  37. #undef max
  38. #endif
  39. #define max(a,b) ((a)>(b)?(a):(b))
  40. /***********************************************************************
  41.  *
  42.  * Private class method prototypes
  43.  *
  44.  ***********************************************************************/
  45. /* unpublished debug routines */
  46. extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
  47. extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
  48. extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
  49. static void set_defaults_(FLAC__SeekableStreamEncoder *encoder);
  50. static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
  51. static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
  52. /***********************************************************************
  53.  *
  54.  * Private class data
  55.  *
  56.  ***********************************************************************/
  57. typedef struct FLAC__SeekableStreamEncoderPrivate {
  58. FLAC__SeekableStreamEncoderSeekCallback seek_callback;
  59. FLAC__SeekableStreamEncoderTellCallback tell_callback;
  60. FLAC__SeekableStreamEncoderWriteCallback write_callback;
  61. void *client_data;
  62. FLAC__StreamEncoder *stream_encoder;
  63. FLAC__StreamMetadata_SeekTable *seek_table;
  64. /* internal vars (all the above are class settings) */
  65. unsigned first_seekpoint_to_check;
  66. FLAC__uint64 samples_written;
  67. } FLAC__SeekableStreamEncoderPrivate;
  68. /***********************************************************************
  69.  *
  70.  * Public static class data
  71.  *
  72.  ***********************************************************************/
  73. FLAC_API const char * const FLAC__SeekableStreamEncoderStateString[] = {
  74. "FLAC__SEEKABLE_STREAM_ENCODER_OK",
  75. "FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR",
  76. "FLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
  77. "FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR",
  78. "FLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
  79. "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR",
  80. "FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR",
  81. "FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED",
  82. "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK",
  83. "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE",
  84. "FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED"
  85. };
  86. FLAC_API const char * const FLAC__SeekableStreamEncoderSeekStatusString[] = {
  87. "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK",
  88. "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR"
  89. };
  90. FLAC_API const char * const FLAC__SeekableStreamEncoderTellStatusString[] = {
  91. "FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK",
  92. "FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR"
  93. };
  94. /***********************************************************************
  95.  *
  96.  * Class constructor/destructor
  97.  *
  98.  ***********************************************************************/
  99. FLAC_API FLAC__SeekableStreamEncoder *FLAC__seekable_stream_encoder_new()
  100. {
  101. FLAC__SeekableStreamEncoder *encoder;
  102. FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
  103. encoder = (FLAC__SeekableStreamEncoder*)calloc(1, sizeof(FLAC__SeekableStreamEncoder));
  104. if(encoder == 0) {
  105. return 0;
  106. }
  107. encoder->protected_ = (FLAC__SeekableStreamEncoderProtected*)calloc(1, sizeof(FLAC__SeekableStreamEncoderProtected));
  108. if(encoder->protected_ == 0) {
  109. free(encoder);
  110. return 0;
  111. }
  112. encoder->private_ = (FLAC__SeekableStreamEncoderPrivate*)calloc(1, sizeof(FLAC__SeekableStreamEncoderPrivate));
  113. if(encoder->private_ == 0) {
  114. free(encoder->protected_);
  115. free(encoder);
  116. return 0;
  117. }
  118. encoder->private_->stream_encoder = FLAC__stream_encoder_new();
  119. if(0 == encoder->private_->stream_encoder) {
  120. free(encoder->private_);
  121. free(encoder->protected_);
  122. free(encoder);
  123. return 0;
  124. }
  125. set_defaults_(encoder);
  126. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
  127. return encoder;
  128. }
  129. FLAC_API void FLAC__seekable_stream_encoder_delete(FLAC__SeekableStreamEncoder *encoder)
  130. {
  131. FLAC__ASSERT(0 != encoder);
  132. FLAC__ASSERT(0 != encoder->protected_);
  133. FLAC__ASSERT(0 != encoder->private_);
  134. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  135. (void)FLAC__seekable_stream_encoder_finish(encoder);
  136. FLAC__stream_encoder_delete(encoder->private_->stream_encoder);
  137. free(encoder->private_);
  138. free(encoder->protected_);
  139. free(encoder);
  140. }
  141. /***********************************************************************
  142.  *
  143.  * Public class methods
  144.  *
  145.  ***********************************************************************/
  146. FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_init(FLAC__SeekableStreamEncoder *encoder)
  147. {
  148. FLAC__ASSERT(0 != encoder);
  149. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  150. return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED;
  151. if(0 == encoder->private_->seek_callback || 0 == encoder->private_->tell_callback || 0 == encoder->private_->write_callback)
  152. return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK;
  153. if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table))
  154. return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE;
  155. /*
  156.  * These must be done before we init the stream encoder because that
  157.  * calls the write_callback, which uses these values.
  158.  */
  159. encoder->private_->first_seekpoint_to_check = 0;
  160. encoder->private_->samples_written = 0;
  161. encoder->protected_->streaminfo_offset = 0;
  162. encoder->protected_->seektable_offset = 0;
  163. encoder->protected_->audio_offset = 0;
  164. FLAC__stream_encoder_set_write_callback(encoder->private_->stream_encoder, write_callback_);
  165. FLAC__stream_encoder_set_metadata_callback(encoder->private_->stream_encoder, metadata_callback_);
  166. FLAC__stream_encoder_set_client_data(encoder->private_->stream_encoder, encoder);
  167. if(FLAC__stream_encoder_init(encoder->private_->stream_encoder) != FLAC__STREAM_ENCODER_OK)
  168. return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
  169. /*
  170.  * Initializing the stream encoder writes all the metadata, so we
  171.  * save the stream offset now.
  172.  */
  173. if(encoder->private_->tell_callback(encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
  174. return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
  175. return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_OK;
  176. }
  177. FLAC_API void FLAC__seekable_stream_encoder_finish(FLAC__SeekableStreamEncoder *encoder)
  178. {
  179. FLAC__ASSERT(0 != encoder);
  180. FLAC__ASSERT(0 != encoder->private_);
  181. FLAC__ASSERT(0 != encoder->protected_);
  182. if(encoder->protected_->state == FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  183. return;
  184. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  185. FLAC__stream_encoder_finish(encoder->private_->stream_encoder);
  186. set_defaults_(encoder);
  187. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
  188. }
  189. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_verify(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  190. {
  191. FLAC__ASSERT(0 != encoder);
  192. FLAC__ASSERT(0 != encoder->private_);
  193. FLAC__ASSERT(0 != encoder->protected_);
  194. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  195. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  196. return false;
  197. return FLAC__stream_encoder_set_verify(encoder->private_->stream_encoder, value);
  198. }
  199. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_streamable_subset(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  200. {
  201. FLAC__ASSERT(0 != encoder);
  202. FLAC__ASSERT(0 != encoder->private_);
  203. FLAC__ASSERT(0 != encoder->protected_);
  204. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  205. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  206. return false;
  207. return FLAC__stream_encoder_set_streamable_subset(encoder->private_->stream_encoder, value);
  208. }
  209. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  210. {
  211. FLAC__ASSERT(0 != encoder);
  212. FLAC__ASSERT(0 != encoder->private_);
  213. FLAC__ASSERT(0 != encoder->protected_);
  214. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  215. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  216. return false;
  217. return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->stream_encoder, value);
  218. }
  219. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  220. {
  221. FLAC__ASSERT(0 != encoder);
  222. FLAC__ASSERT(0 != encoder->private_);
  223. FLAC__ASSERT(0 != encoder->protected_);
  224. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  225. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  226. return false;
  227. return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->stream_encoder, value);
  228. }
  229. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_channels(FLAC__SeekableStreamEncoder *encoder, unsigned value)
  230. {
  231. FLAC__ASSERT(0 != encoder);
  232. FLAC__ASSERT(0 != encoder->private_);
  233. FLAC__ASSERT(0 != encoder->protected_);
  234. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  235. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  236. return false;
  237. return FLAC__stream_encoder_set_channels(encoder->private_->stream_encoder, value);
  238. }
  239. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_bits_per_sample(FLAC__SeekableStreamEncoder *encoder, unsigned value)
  240. {
  241. FLAC__ASSERT(0 != encoder);
  242. FLAC__ASSERT(0 != encoder->private_);
  243. FLAC__ASSERT(0 != encoder->protected_);
  244. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  245. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  246. return false;
  247. return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->stream_encoder, value);
  248. }
  249. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__SeekableStreamEncoder *encoder, unsigned value)
  250. {
  251. FLAC__ASSERT(0 != encoder);
  252. FLAC__ASSERT(0 != encoder->private_);
  253. FLAC__ASSERT(0 != encoder->protected_);
  254. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  255. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  256. return false;
  257. return FLAC__stream_encoder_set_sample_rate(encoder->private_->stream_encoder, value);
  258. }
  259. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value)
  260. {
  261. FLAC__ASSERT(0 != encoder);
  262. FLAC__ASSERT(0 != encoder->private_);
  263. FLAC__ASSERT(0 != encoder->protected_);
  264. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  265. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  266. return false;
  267. return FLAC__stream_encoder_set_blocksize(encoder->private_->stream_encoder, value);
  268. }
  269. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
  270. {
  271. FLAC__ASSERT(0 != encoder);
  272. FLAC__ASSERT(0 != encoder->private_);
  273. FLAC__ASSERT(0 != encoder->protected_);
  274. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  275. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  276. return false;
  277. return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->stream_encoder, value);
  278. }
  279. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_qlp_coeff_precision(FLAC__SeekableStreamEncoder *encoder, unsigned value)
  280. {
  281. FLAC__ASSERT(0 != encoder);
  282. FLAC__ASSERT(0 != encoder->private_);
  283. FLAC__ASSERT(0 != encoder->protected_);
  284. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  285. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  286. return false;
  287. return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->stream_encoder, value);
  288. }
  289. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  290. {
  291. FLAC__ASSERT(0 != encoder);
  292. FLAC__ASSERT(0 != encoder->private_);
  293. FLAC__ASSERT(0 != encoder->protected_);
  294. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  295. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  296. return false;
  297. return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->stream_encoder, value);
  298. }
  299. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_escape_coding(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  300. {
  301. FLAC__ASSERT(0 != encoder);
  302. FLAC__ASSERT(0 != encoder->private_);
  303. FLAC__ASSERT(0 != encoder->protected_);
  304. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  305. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  306. return false;
  307. return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->stream_encoder, value);
  308. }
  309. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  310. {
  311. FLAC__ASSERT(0 != encoder);
  312. FLAC__ASSERT(0 != encoder->private_);
  313. FLAC__ASSERT(0 != encoder->protected_);
  314. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  315. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  316. return false;
  317. return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->stream_encoder, value);
  318. }
  319. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_min_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
  320. {
  321. FLAC__ASSERT(0 != encoder);
  322. FLAC__ASSERT(0 != encoder->private_);
  323. FLAC__ASSERT(0 != encoder->protected_);
  324. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  325. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  326. return false;
  327. return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->stream_encoder, value);
  328. }
  329. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
  330. {
  331. FLAC__ASSERT(0 != encoder);
  332. FLAC__ASSERT(0 != encoder->private_);
  333. FLAC__ASSERT(0 != encoder->protected_);
  334. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  335. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  336. return false;
  337. return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->stream_encoder, value);
  338. }
  339. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(FLAC__SeekableStreamEncoder *encoder, unsigned value)
  340. {
  341. FLAC__ASSERT(0 != encoder);
  342. FLAC__ASSERT(0 != encoder->private_);
  343. FLAC__ASSERT(0 != encoder->protected_);
  344. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  345. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  346. return false;
  347. return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->stream_encoder, value);
  348. }
  349. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_total_samples_estimate(FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value)
  350. {
  351. FLAC__ASSERT(0 != encoder);
  352. FLAC__ASSERT(0 != encoder->private_);
  353. FLAC__ASSERT(0 != encoder->protected_);
  354. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  355. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  356. return false;
  357. return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->stream_encoder, value);
  358. }
  359. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_metadata(FLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
  360. {
  361. FLAC__ASSERT(0 != encoder);
  362. FLAC__ASSERT(0 != encoder->private_);
  363. FLAC__ASSERT(0 != encoder->protected_);
  364. FLAC__ASSERT(0 != encoder->private_->stream_encoder);
  365. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  366. return false;
  367. if(0 != metadata && num_blocks > 0) {
  368. unsigned i;
  369. for(i = 0; i < num_blocks; i++) {
  370. if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
  371. encoder->private_->seek_table = &metadata[i]->data.seek_table;
  372. break; /* take only the first one */
  373. }
  374. }
  375. }
  376. return FLAC__stream_encoder_set_metadata(encoder->private_->stream_encoder, metadata, num_blocks);
  377. }
  378. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_seek_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderSeekCallback value)
  379. {
  380. FLAC__ASSERT(0 != encoder);
  381. FLAC__ASSERT(0 != encoder->private_);
  382. FLAC__ASSERT(0 != encoder->protected_);
  383. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  384. return false;
  385. encoder->private_->seek_callback = value;
  386. return true;
  387. }
  388. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_tell_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderTellCallback value)
  389. {
  390. FLAC__ASSERT(0 != encoder);
  391. FLAC__ASSERT(0 != encoder->private_);
  392. FLAC__ASSERT(0 != encoder->protected_);
  393. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  394. return false;
  395. encoder->private_->tell_callback = value;
  396. return true;
  397. }
  398. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_write_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderWriteCallback value)
  399. {
  400. FLAC__ASSERT(0 != encoder);
  401. FLAC__ASSERT(0 != encoder->private_);
  402. FLAC__ASSERT(0 != encoder->protected_);
  403. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  404. return false;
  405. encoder->private_->write_callback = value;
  406. return true;
  407. }
  408. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_client_data(FLAC__SeekableStreamEncoder *encoder, void *value)
  409. {
  410. FLAC__ASSERT(0 != encoder);
  411. FLAC__ASSERT(0 != encoder->private_);
  412. FLAC__ASSERT(0 != encoder->protected_);
  413. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  414. return false;
  415. encoder->private_->client_data = value;
  416. return true;
  417. }
  418. /*
  419.  * These three functions are not static, but not publically exposed in
  420.  * include/FLAC/ either.  They are used by the test suite.
  421.  */
  422. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  423. {
  424. FLAC__ASSERT(0 != encoder);
  425. FLAC__ASSERT(0 != encoder->private_);
  426. FLAC__ASSERT(0 != encoder->protected_);
  427. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  428. return false;
  429. return FLAC__stream_encoder_disable_constant_subframes(encoder->private_->stream_encoder, value);
  430. }
  431. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  432. {
  433. FLAC__ASSERT(0 != encoder);
  434. FLAC__ASSERT(0 != encoder->private_);
  435. FLAC__ASSERT(0 != encoder->protected_);
  436. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  437. return false;
  438. return FLAC__stream_encoder_disable_fixed_subframes(encoder->private_->stream_encoder, value);
  439. }
  440. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
  441. {
  442. FLAC__ASSERT(0 != encoder);
  443. FLAC__ASSERT(0 != encoder->private_);
  444. FLAC__ASSERT(0 != encoder->protected_);
  445. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
  446. return false;
  447. return FLAC__stream_encoder_disable_verbatim_subframes(encoder->private_->stream_encoder, value);
  448. }
  449. FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_state(const FLAC__SeekableStreamEncoder *encoder)
  450. {
  451. FLAC__ASSERT(0 != encoder);
  452. FLAC__ASSERT(0 != encoder->protected_);
  453. return encoder->protected_->state;
  454. }
  455. FLAC_API FLAC__StreamEncoderState FLAC__seekable_stream_encoder_get_stream_encoder_state(const FLAC__SeekableStreamEncoder *encoder)
  456. {
  457. FLAC__ASSERT(0 != encoder);
  458. FLAC__ASSERT(0 != encoder->private_);
  459. return FLAC__stream_encoder_get_state(encoder->private_->stream_encoder);
  460. }
  461. FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_encoder_get_verify_decoder_state(const FLAC__SeekableStreamEncoder *encoder)
  462. {
  463. FLAC__ASSERT(0 != encoder);
  464. FLAC__ASSERT(0 != encoder->private_);
  465. return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->stream_encoder);
  466. }
  467. FLAC_API const char *FLAC__seekable_stream_encoder_get_resolved_state_string(const FLAC__SeekableStreamEncoder *encoder)
  468. {
  469. if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR)
  470. return FLAC__SeekableStreamEncoderStateString[encoder->protected_->state];
  471. else
  472. return FLAC__stream_encoder_get_resolved_state_string(encoder->private_->stream_encoder);
  473. }
  474. FLAC_API void FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
  475. {
  476. FLAC__ASSERT(0 != encoder);
  477. FLAC__ASSERT(0 != encoder->private_);
  478. FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
  479. }
  480. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_verify(const FLAC__SeekableStreamEncoder *encoder)
  481. {
  482. FLAC__ASSERT(0 != encoder);
  483. FLAC__ASSERT(0 != encoder->private_);
  484. return FLAC__stream_encoder_get_verify(encoder->private_->stream_encoder);
  485. }
  486. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_streamable_subset(const FLAC__SeekableStreamEncoder *encoder)
  487. {
  488. FLAC__ASSERT(0 != encoder);
  489. FLAC__ASSERT(0 != encoder->private_);
  490. return FLAC__stream_encoder_get_streamable_subset(encoder->private_->stream_encoder);
  491. }
  492. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
  493. {
  494. FLAC__ASSERT(0 != encoder);
  495. FLAC__ASSERT(0 != encoder->private_);
  496. return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->stream_encoder);
  497. }
  498. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
  499. {
  500. FLAC__ASSERT(0 != encoder);
  501. FLAC__ASSERT(0 != encoder->private_);
  502. return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->stream_encoder);
  503. }
  504. FLAC_API unsigned FLAC__seekable_stream_encoder_get_channels(const FLAC__SeekableStreamEncoder *encoder)
  505. {
  506. FLAC__ASSERT(0 != encoder);
  507. FLAC__ASSERT(0 != encoder->private_);
  508. return FLAC__stream_encoder_get_channels(encoder->private_->stream_encoder);
  509. }
  510. FLAC_API unsigned FLAC__seekable_stream_encoder_get_bits_per_sample(const FLAC__SeekableStreamEncoder *encoder)
  511. {
  512. FLAC__ASSERT(0 != encoder);
  513. FLAC__ASSERT(0 != encoder->private_);
  514. return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->stream_encoder);
  515. }
  516. FLAC_API unsigned FLAC__seekable_stream_encoder_get_sample_rate(const FLAC__SeekableStreamEncoder *encoder)
  517. {
  518. FLAC__ASSERT(0 != encoder);
  519. FLAC__ASSERT(0 != encoder->private_);
  520. return FLAC__stream_encoder_get_sample_rate(encoder->private_->stream_encoder);
  521. }
  522. FLAC_API unsigned FLAC__seekable_stream_encoder_get_blocksize(const FLAC__SeekableStreamEncoder *encoder)
  523. {
  524. FLAC__ASSERT(0 != encoder);
  525. FLAC__ASSERT(0 != encoder->private_);
  526. return FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder);
  527. }
  528. FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_lpc_order(const FLAC__SeekableStreamEncoder *encoder)
  529. {
  530. FLAC__ASSERT(0 != encoder);
  531. FLAC__ASSERT(0 != encoder->private_);
  532. return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->stream_encoder);
  533. }
  534. FLAC_API unsigned FLAC__seekable_stream_encoder_get_qlp_coeff_precision(const FLAC__SeekableStreamEncoder *encoder)
  535. {
  536. FLAC__ASSERT(0 != encoder);
  537. FLAC__ASSERT(0 != encoder->private_);
  538. return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->stream_encoder);
  539. }
  540. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__SeekableStreamEncoder *encoder)
  541. {
  542. FLAC__ASSERT(0 != encoder);
  543. FLAC__ASSERT(0 != encoder->private_);
  544. return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->stream_encoder);
  545. }
  546. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_escape_coding(const FLAC__SeekableStreamEncoder *encoder)
  547. {
  548. FLAC__ASSERT(0 != encoder);
  549. FLAC__ASSERT(0 != encoder->private_);
  550. return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->stream_encoder);
  551. }
  552. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const FLAC__SeekableStreamEncoder *encoder)
  553. {
  554. FLAC__ASSERT(0 != encoder);
  555. FLAC__ASSERT(0 != encoder->private_);
  556. return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->stream_encoder);
  557. }
  558. FLAC_API unsigned FLAC__seekable_stream_encoder_get_min_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
  559. {
  560. FLAC__ASSERT(0 != encoder);
  561. FLAC__ASSERT(0 != encoder->private_);
  562. return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->stream_encoder);
  563. }
  564. FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
  565. {
  566. FLAC__ASSERT(0 != encoder);
  567. FLAC__ASSERT(0 != encoder->private_);
  568. return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->stream_encoder);
  569. }
  570. FLAC_API unsigned FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const FLAC__SeekableStreamEncoder *encoder)
  571. {
  572. FLAC__ASSERT(0 != encoder);
  573. FLAC__ASSERT(0 != encoder->private_);
  574. return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->stream_encoder);
  575. }
  576. FLAC_API FLAC__uint64 FLAC__seekable_stream_encoder_get_total_samples_estimate(const FLAC__SeekableStreamEncoder *encoder)
  577. {
  578. FLAC__ASSERT(0 != encoder);
  579. FLAC__ASSERT(0 != encoder->private_);
  580. return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->stream_encoder);
  581. }
  582. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
  583. {
  584. FLAC__ASSERT(0 != encoder);
  585. FLAC__ASSERT(0 != encoder->private_);
  586. if(!FLAC__stream_encoder_process(encoder->private_->stream_encoder, buffer, samples)) {
  587. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
  588. return false;
  589. }
  590. else
  591. return true;
  592. }
  593. /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
  594. FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process_interleaved(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
  595. {
  596. FLAC__ASSERT(0 != encoder);
  597. FLAC__ASSERT(0 != encoder->private_);
  598. if(!FLAC__stream_encoder_process_interleaved(encoder->private_->stream_encoder, buffer, samples)) {
  599. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
  600. return false;
  601. }
  602. else
  603. return true;
  604. }
  605. /***********************************************************************
  606.  *
  607.  * Private class methods
  608.  *
  609.  ***********************************************************************/
  610. void set_defaults_(FLAC__SeekableStreamEncoder *encoder)
  611. {
  612. FLAC__ASSERT(0 != encoder);
  613. FLAC__ASSERT(0 != encoder->private_);
  614. FLAC__ASSERT(0 != encoder->protected_);
  615. encoder->private_->seek_callback = 0;
  616. encoder->private_->tell_callback = 0;
  617. encoder->private_->write_callback = 0;
  618. encoder->private_->client_data = 0;
  619. encoder->private_->seek_table = 0;
  620. }
  621. FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
  622. {
  623. FLAC__SeekableStreamEncoder *encoder = (FLAC__SeekableStreamEncoder*)client_data;
  624. FLAC__StreamEncoderWriteStatus status;
  625. FLAC__uint64 output_position;
  626. (void)unused; /* silence compiler warning about unused parameter */
  627. FLAC__ASSERT(encoder->private_->stream_encoder == unused);
  628. if(encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
  629. return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
  630. /*
  631.  * Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets.
  632.  */
  633. if(samples == 0) {
  634. FLAC__MetadataType type = (buffer[0] & 0x7f);
  635. if(type == FLAC__METADATA_TYPE_STREAMINFO)
  636. encoder->protected_->streaminfo_offset = output_position;
  637. else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0)
  638. encoder->protected_->seektable_offset = output_position;
  639. }
  640. /*
  641.  * Mark the current seek point if hit (if audio_offset == 0 that
  642.  * means we're still writing metadata and haven't hit the first
  643.  * frame yet)
  644.  */
  645. if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) {
  646. const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder);
  647. const FLAC__uint64 frame_first_sample = encoder->private_->samples_written;
  648. const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
  649. FLAC__uint64 test_sample;
  650. unsigned i;
  651. for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) {
  652. test_sample = encoder->private_->seek_table->points[i].sample_number;
  653. if(test_sample > frame_last_sample) {
  654. break;
  655. }
  656. else if(test_sample >= frame_first_sample) {
  657. encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
  658. encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset;
  659. encoder->private_->seek_table->points[i].frame_samples = blocksize;
  660. encoder->private_->first_seekpoint_to_check++;
  661. /* DO NOT: "break;" and here's why:
  662.  * The seektable template may contain more than one target
  663.  * sample for any given frame; we will keep looping, generating
  664.  * duplicate seekpoints for them, and we'll clean it up later,
  665.  * just before writing the seektable back to the metadata.
  666.  */
  667. }
  668. else {
  669. encoder->private_->first_seekpoint_to_check++;
  670. }
  671. }
  672. }
  673. status = encoder->private_->write_callback(encoder, buffer, bytes, samples, current_frame, encoder->private_->client_data);
  674. if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
  675. encoder->private_->samples_written += samples;
  676. }
  677. else
  678. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
  679. return status;
  680. }
  681. void metadata_callback_(const FLAC__StreamEncoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
  682. {
  683. FLAC__SeekableStreamEncoder *encoder = (FLAC__SeekableStreamEncoder*)client_data;
  684. FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
  685. const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
  686. const unsigned min_framesize = metadata->data.stream_info.min_framesize;
  687. const unsigned max_framesize = metadata->data.stream_info.max_framesize;
  688. const unsigned bps = metadata->data.stream_info.bits_per_sample;
  689. FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
  690. /* We get called by the stream encoder when the encoding process
  691.  * has finished so that we can update the STREAMINFO and SEEKTABLE
  692.  * blocks.
  693.  */
  694. (void)unused; /* silence compiler warning about unused parameter */
  695. FLAC__ASSERT(encoder->private_->stream_encoder == unused);
  696. /*@@@ reopen callback here?  The docs currently require user to open files in update mode from the start */
  697. /* All this is based on intimate knowledge of the stream header
  698.  * layout, but a change to the header format that would break this
  699.  * would also break all streams encoded in the previous format.
  700.  */
  701. /*
  702.  * Write MD5 signature
  703.  */
  704. {
  705. const unsigned md5_offset =
  706. FLAC__STREAM_METADATA_HEADER_LENGTH +
  707. (
  708. FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
  709. FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
  710. FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
  711. FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
  712. FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
  713. FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
  714. FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
  715. FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
  716. ) / 8;
  717. if(encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + md5_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
  718. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
  719. return;
  720. }
  721. if(encoder->private_->write_callback(encoder, metadata->data.stream_info.md5sum, 16, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
  722. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
  723. return;
  724. }
  725. }
  726. /*
  727.  * Write total samples
  728.  */
  729. {
  730. const unsigned total_samples_byte_offset =
  731. FLAC__STREAM_METADATA_HEADER_LENGTH +
  732. (
  733. FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
  734. FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
  735. FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
  736. FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
  737. FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
  738. FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
  739. FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
  740. - 4
  741. ) / 8;
  742. b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F);
  743. b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
  744. b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
  745. b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
  746. b[4] = (FLAC__byte)(samples & 0xFF);
  747. if(encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + total_samples_byte_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
  748. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
  749. return;
  750. }
  751. if(encoder->private_->write_callback(encoder, b, 5, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
  752. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
  753. return;
  754. }
  755. }
  756. /*
  757.  * Write min/max framesize
  758.  */
  759. {
  760. const unsigned min_framesize_offset =
  761. FLAC__STREAM_METADATA_HEADER_LENGTH +
  762. (
  763. FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
  764. FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
  765. ) / 8;
  766. b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
  767. b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
  768. b[2] = (FLAC__byte)(min_framesize & 0xFF);
  769. b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
  770. b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
  771. b[5] = (FLAC__byte)(max_framesize & 0xFF);
  772. if(encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + min_framesize_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
  773. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
  774. return;
  775. }
  776. if(encoder->private_->write_callback(encoder, b, 6, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
  777. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
  778. return;
  779. }
  780. }
  781. /*
  782.  * Write seektable
  783.  */
  784. if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
  785. unsigned i;
  786. FLAC__format_seektable_sort(encoder->private_->seek_table);
  787. FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
  788. if(encoder->private_->seek_callback(encoder, encoder->protected_->seektable_offset + FLAC__STREAM_METADATA_HEADER_LENGTH, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
  789. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
  790. return;
  791. }
  792. for(i = 0; i < encoder->private_->seek_table->num_points; i++) {
  793. FLAC__uint64 xx;
  794. unsigned x;
  795. xx = encoder->private_->seek_table->points[i].sample_number;
  796. b[7] = (FLAC__byte)xx; xx >>= 8;
  797. b[6] = (FLAC__byte)xx; xx >>= 8;
  798. b[5] = (FLAC__byte)xx; xx >>= 8;
  799. b[4] = (FLAC__byte)xx; xx >>= 8;
  800. b[3] = (FLAC__byte)xx; xx >>= 8;
  801. b[2] = (FLAC__byte)xx; xx >>= 8;
  802. b[1] = (FLAC__byte)xx; xx >>= 8;
  803. b[0] = (FLAC__byte)xx; xx >>= 8;
  804. xx = encoder->private_->seek_table->points[i].stream_offset;
  805. b[15] = (FLAC__byte)xx; xx >>= 8;
  806. b[14] = (FLAC__byte)xx; xx >>= 8;
  807. b[13] = (FLAC__byte)xx; xx >>= 8;
  808. b[12] = (FLAC__byte)xx; xx >>= 8;
  809. b[11] = (FLAC__byte)xx; xx >>= 8;
  810. b[10] = (FLAC__byte)xx; xx >>= 8;
  811. b[9] = (FLAC__byte)xx; xx >>= 8;
  812. b[8] = (FLAC__byte)xx; xx >>= 8;
  813. x = encoder->private_->seek_table->points[i].frame_samples;
  814. b[17] = (FLAC__byte)x; x >>= 8;
  815. b[16] = (FLAC__byte)x; x >>= 8;
  816. if(encoder->private_->write_callback(encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
  817. encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
  818. return;
  819. }
  820. }
  821. }
  822. }