The "GR-PEACH_Audio_Playback_7InchLCD_Sample" is a sample code that can provides high-resolution audio playback of FLAC format files. It also allows the user to audio-playback control functions such as play, pause, and stop by manipulating key switches.
Dependencies: GR-PEACH_video R_BSP TLV320_RBSP USBHost_custom
Fork of GR-PEACH_Audio_Playback_Sample by
format.c
00001 /* libFLAC - Free Lossless Audio Codec library 00002 * Copyright (C) 2000-2009 Josh Coalson 00003 * Copyright (C) 2011-2014 Xiph.Org Foundation 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 00009 * - Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 00012 * - Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * 00016 * - Neither the name of the Xiph.org Foundation nor the names of its 00017 * contributors may be used to endorse or promote products derived from 00018 * this software without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00021 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 00024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 00033 #ifdef HAVE_CONFIG_H 00034 # include <config.h> 00035 #endif 00036 00037 #include <stdio.h> 00038 #include <stdlib.h> /* for qsort() */ 00039 #include <string.h> /* for memset() */ 00040 #include "FLAC/assert.h" 00041 #include "FLAC/format.h" 00042 #include "share/compat.h" 00043 #include "private/format.h" 00044 #include "private/macros.h" 00045 00046 #if(1) /* mbed */ 00047 #define VERSION "1.3.1" 00048 #endif /* end mbed */ 00049 00050 /* VERSION should come from configure */ 00051 FLAC_API const char *FLAC__VERSION_STRING = VERSION; 00052 00053 FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20141125"; 00054 00055 FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; 00056 FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143; 00057 FLAC_API const unsigned FLAC__STREAM_SYNC_LEN = 32; /* bits */ 00058 00059 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */ 00060 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */ 00061 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */ 00062 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */ 00063 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */ 00064 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */ 00065 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */ 00066 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */ 00067 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */ 00068 00069 FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */ 00070 00071 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */ 00072 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */ 00073 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */ 00074 00075 FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff); 00076 00077 FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */ 00078 FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */ 00079 00080 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */ 00081 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */ 00082 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */ 00083 00084 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */ 00085 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */ 00086 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */ 00087 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */ 00088 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */ 00089 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */ 00090 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */ 00091 00092 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */ 00093 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */ 00094 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */ 00095 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */ 00096 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */ 00097 00098 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */ 00099 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */ 00100 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */ 00101 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */ 00102 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */ 00103 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */ 00104 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */ 00105 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */ 00106 00107 FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */ 00108 FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */ 00109 FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */ 00110 00111 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe; 00112 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */ 00113 FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */ 00114 FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */ 00115 FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */ 00116 FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */ 00117 FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */ 00118 FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */ 00119 FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */ 00120 FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */ 00121 00122 FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */ 00123 00124 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */ 00125 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */ 00126 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */ 00127 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */ 00128 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */ 00129 00130 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */ 00131 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */ 00132 00133 FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = { 00134 "PARTITIONED_RICE", 00135 "PARTITIONED_RICE2" 00136 }; 00137 00138 FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */ 00139 FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */ 00140 00141 FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */ 00142 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */ 00143 FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */ 00144 00145 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00; 00146 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02; 00147 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10; 00148 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40; 00149 00150 FLAC_API const char * const FLAC__SubframeTypeString[] = { 00151 "CONSTANT", 00152 "VERBATIM", 00153 "FIXED", 00154 "LPC" 00155 }; 00156 00157 FLAC_API const char * const FLAC__ChannelAssignmentString[] = { 00158 "INDEPENDENT", 00159 "LEFT_SIDE", 00160 "RIGHT_SIDE", 00161 "MID_SIDE" 00162 }; 00163 00164 FLAC_API const char * const FLAC__FrameNumberTypeString[] = { 00165 "FRAME_NUMBER_TYPE_FRAME_NUMBER", 00166 "FRAME_NUMBER_TYPE_SAMPLE_NUMBER" 00167 }; 00168 00169 FLAC_API const char * const FLAC__MetadataTypeString[] = { 00170 "STREAMINFO", 00171 "PADDING", 00172 "APPLICATION", 00173 "SEEKTABLE", 00174 "VORBIS_COMMENT", 00175 "CUESHEET", 00176 "PICTURE" 00177 }; 00178 00179 FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = { 00180 "Other", 00181 "32x32 pixels 'file icon' (PNG only)", 00182 "Other file icon", 00183 "Cover (front)", 00184 "Cover (back)", 00185 "Leaflet page", 00186 "Media (e.g. label side of CD)", 00187 "Lead artist/lead performer/soloist", 00188 "Artist/performer", 00189 "Conductor", 00190 "Band/Orchestra", 00191 "Composer", 00192 "Lyricist/text writer", 00193 "Recording Location", 00194 "During recording", 00195 "During performance", 00196 "Movie/video screen capture", 00197 "A bright coloured fish", 00198 "Illustration", 00199 "Band/artist logotype", 00200 "Publisher/Studio logotype" 00201 }; 00202 00203 FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate) 00204 { 00205 if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) { 00206 return false; 00207 } 00208 else 00209 return true; 00210 } 00211 00212 FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate) 00213 { 00214 if(blocksize > 16384) 00215 return false; 00216 else if(sample_rate <= 48000 && blocksize > 4608) 00217 return false; 00218 else 00219 return true; 00220 } 00221 00222 FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate) 00223 { 00224 if( 00225 !FLAC__format_sample_rate_is_valid(sample_rate) || 00226 ( 00227 sample_rate >= (1u << 16) && 00228 !(sample_rate % 1000 == 0 || sample_rate % 10 == 0) 00229 ) 00230 ) { 00231 return false; 00232 } 00233 else 00234 return true; 00235 } 00236 00237 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ 00238 FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table) 00239 { 00240 unsigned i; 00241 FLAC__uint64 prev_sample_number = 0; 00242 FLAC__bool got_prev = false; 00243 00244 FLAC__ASSERT(0 != seek_table); 00245 00246 for(i = 0; i < seek_table->num_points; i++) { 00247 if(got_prev) { 00248 if( 00249 seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && 00250 seek_table->points[i].sample_number <= prev_sample_number 00251 ) 00252 return false; 00253 } 00254 prev_sample_number = seek_table->points[i].sample_number; 00255 got_prev = true; 00256 } 00257 00258 return true; 00259 } 00260 00261 /* used as the sort predicate for qsort() */ 00262 static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r) 00263 { 00264 /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */ 00265 if(l->sample_number == r->sample_number) 00266 return 0; 00267 else if(l->sample_number < r->sample_number) 00268 return -1; 00269 else 00270 return 1; 00271 } 00272 00273 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ 00274 FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table) 00275 { 00276 unsigned i, j; 00277 FLAC__bool first; 00278 00279 FLAC__ASSERT(0 != seek_table); 00280 00281 /* sort the seekpoints */ 00282 qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_); 00283 00284 /* uniquify the seekpoints */ 00285 first = true; 00286 for(i = j = 0; i < seek_table->num_points; i++) { 00287 if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) { 00288 if(!first) { 00289 if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number) 00290 continue; 00291 } 00292 } 00293 first = false; 00294 seek_table->points[j++] = seek_table->points[i]; 00295 } 00296 00297 for(i = j; i < seek_table->num_points; i++) { 00298 seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; 00299 seek_table->points[i].stream_offset = 0; 00300 seek_table->points[i].frame_samples = 0; 00301 } 00302 00303 return j; 00304 } 00305 00306 /* 00307 * also disallows non-shortest-form encodings, c.f. 00308 * http://www.unicode.org/versions/corrigendum1.html 00309 * and a more clear explanation at the end of this section: 00310 * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 00311 */ 00312 static unsigned utf8len_(const FLAC__byte *utf8) 00313 { 00314 FLAC__ASSERT(0 != utf8); 00315 if ((utf8[0] & 0x80) == 0) { 00316 return 1; 00317 } 00318 else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) { 00319 if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */ 00320 return 0; 00321 return 2; 00322 } 00323 else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) { 00324 if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */ 00325 return 0; 00326 /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */ 00327 if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */ 00328 return 0; 00329 if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */ 00330 return 0; 00331 return 3; 00332 } 00333 else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) { 00334 if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */ 00335 return 0; 00336 return 4; 00337 } 00338 else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) { 00339 if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */ 00340 return 0; 00341 return 5; 00342 } 00343 else if ((utf8[0] & 0xFE) == 0xFC && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80 && (utf8[5] & 0xC0) == 0x80) { 00344 if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */ 00345 return 0; 00346 return 6; 00347 } 00348 else { 00349 return 0; 00350 } 00351 } 00352 00353 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name) 00354 { 00355 char c; 00356 for(c = *name; c; c = *(++name)) 00357 if(c < 0x20 || c == 0x3d || c > 0x7d) 00358 return false; 00359 return true; 00360 } 00361 00362 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length) 00363 { 00364 if(length == (unsigned)(-1)) { 00365 while(*value) { 00366 unsigned n = utf8len_(value); 00367 if(n == 0) 00368 return false; 00369 value += n; 00370 } 00371 } 00372 else { 00373 const FLAC__byte *end = value + length; 00374 while(value < end) { 00375 unsigned n = utf8len_(value); 00376 if(n == 0) 00377 return false; 00378 value += n; 00379 } 00380 if(value != end) 00381 return false; 00382 } 00383 return true; 00384 } 00385 00386 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length) 00387 { 00388 const FLAC__byte *s, *end; 00389 00390 for(s = entry, end = s + length; s < end && *s != '='; s++) { 00391 if(*s < 0x20 || *s > 0x7D) 00392 return false; 00393 } 00394 if(s == end) 00395 return false; 00396 00397 s++; /* skip '=' */ 00398 00399 while(s < end) { 00400 unsigned n = utf8len_(s); 00401 if(n == 0) 00402 return false; 00403 s += n; 00404 } 00405 if(s != end) 00406 return false; 00407 00408 return true; 00409 } 00410 00411 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ 00412 FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation) 00413 { 00414 unsigned i, j; 00415 00416 if(check_cd_da_subset) { 00417 if(cue_sheet->lead_in < 2 * 44100) { 00418 if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds"; 00419 return false; 00420 } 00421 if(cue_sheet->lead_in % 588 != 0) { 00422 if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples"; 00423 return false; 00424 } 00425 } 00426 00427 if(cue_sheet->num_tracks == 0) { 00428 if(violation) *violation = "cue sheet must have at least one track (the lead-out)"; 00429 return false; 00430 } 00431 00432 if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) { 00433 if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)"; 00434 return false; 00435 } 00436 00437 for(i = 0; i < cue_sheet->num_tracks; i++) { 00438 if(cue_sheet->tracks[i].number == 0) { 00439 if(violation) *violation = "cue sheet may not have a track number 0"; 00440 return false; 00441 } 00442 00443 if(check_cd_da_subset) { 00444 if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) { 00445 if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170"; 00446 return false; 00447 } 00448 } 00449 00450 if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) { 00451 if(violation) { 00452 if(i == cue_sheet->num_tracks-1) /* the lead-out track... */ 00453 *violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples"; 00454 else 00455 *violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples"; 00456 } 00457 return false; 00458 } 00459 00460 if(i < cue_sheet->num_tracks - 1) { 00461 if(cue_sheet->tracks[i].num_indices == 0) { 00462 if(violation) *violation = "cue sheet track must have at least one index point"; 00463 return false; 00464 } 00465 00466 if(cue_sheet->tracks[i].indices[0].number > 1) { 00467 if(violation) *violation = "cue sheet track's first index number must be 0 or 1"; 00468 return false; 00469 } 00470 } 00471 00472 for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) { 00473 if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) { 00474 if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples"; 00475 return false; 00476 } 00477 00478 if(j > 0) { 00479 if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) { 00480 if(violation) *violation = "cue sheet track index numbers must increase by 1"; 00481 return false; 00482 } 00483 } 00484 } 00485 } 00486 00487 return true; 00488 } 00489 00490 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ 00491 FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation) 00492 { 00493 char *p; 00494 FLAC__byte *b; 00495 00496 for(p = picture->mime_type; *p; p++) { 00497 if(*p < 0x20 || *p > 0x7e) { 00498 if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)"; 00499 return false; 00500 } 00501 } 00502 00503 for(b = picture->description; *b; ) { 00504 unsigned n = utf8len_(b); 00505 if(n == 0) { 00506 if(violation) *violation = "description string must be valid UTF-8"; 00507 return false; 00508 } 00509 b += n; 00510 } 00511 00512 return true; 00513 } 00514 00515 /* 00516 * These routines are private to libFLAC 00517 */ 00518 unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order) 00519 { 00520 return 00521 FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order( 00522 FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize), 00523 blocksize, 00524 predictor_order 00525 ); 00526 } 00527 00528 unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize) 00529 { 00530 unsigned max_rice_partition_order = 0; 00531 while(!(blocksize & 1)) { 00532 max_rice_partition_order++; 00533 blocksize >>= 1; 00534 } 00535 return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order); 00536 } 00537 00538 unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order) 00539 { 00540 unsigned max_rice_partition_order = limit; 00541 00542 while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order) 00543 max_rice_partition_order--; 00544 00545 FLAC__ASSERT( 00546 (max_rice_partition_order == 0 && blocksize >= predictor_order) || 00547 (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order) 00548 ); 00549 00550 return max_rice_partition_order; 00551 } 00552 00553 void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) 00554 { 00555 FLAC__ASSERT(0 != object); 00556 00557 object->parameters = 0; 00558 object->raw_bits = 0; 00559 object->capacity_by_order = 0; 00560 } 00561 00562 void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) 00563 { 00564 FLAC__ASSERT(0 != object); 00565 00566 if(0 != object->parameters) 00567 free(object->parameters); 00568 if(0 != object->raw_bits) 00569 free(object->raw_bits); 00570 FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object); 00571 } 00572 00573 FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order) 00574 { 00575 FLAC__ASSERT(0 != object); 00576 00577 FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits)); 00578 00579 if(object->capacity_by_order < max_partition_order) { 00580 if(0 == (object->parameters = realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order)))) 00581 return false; 00582 if(0 == (object->raw_bits = realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order)))) 00583 return false; 00584 memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order)); 00585 object->capacity_by_order = max_partition_order; 00586 } 00587 00588 return true; 00589 }
Generated on Tue Jul 12 2022 19:32:28 by 1.7.2