Unified · Split
| @@ -144,16 +144,29 @@ one_ non-free-format frame. · 143 unmodified lines | ||
| 144 | 144 | ## Seeking |
| 145 | 145 | |
| 146 | 146 | You can seek to any byte in the stream and call ``mp3dec_decode_frame``; this |
| 147 | −will work in almost all cases, but is not completely guaranteed. If granule data | |
| 148 | −is accidentally detected as a valid MP3 header, short audio artefacting is | |
| 149 | −possible. If the file is known to be cbr, then all frames have equal size and | |
| 147 | +will work in almost all cases, but is not completely guaranteed. Probablility of | |
| 148 | +sync procedure failure lowers when MAX_FRAME_SYNC_MATCHES value grows. Default | |
| 149 | +MAX_FRAME_SYNC_MATCHES=10 and probablility of sync failure should be very low. | |
| 150 | +If granule data is accidentally detected as a valid MP3 header, short audio artefacting is | |
| 151 | +possible. | |
| 152 | + | |
| 153 | +High-level mp3dec_ex_seek function supports precise seek to sample (MP3D_SEEK_TO_SAMPLE) | |
| 154 | +using index and binary search. | |
| 155 | + | |
| 156 | +## Track length detect | |
| 157 | + | |
| 158 | +If the file is known to be cbr, then all frames have equal size and | |
| 150 | 159 | lack ID3 tags, which allows us to decode the first frame and calculate all frame |
| 151 | 160 | positions as ``frame_bytes * N``. However, because of padding, frames can differ |
| 152 | 161 | in size even in this case. |
| 153 | 162 | |
| 163 | +In general case whole stream scan is needed to calculate it's length. Scan can be | |
| 164 | +omitted if vbr tag is present (added by encoders like lame and ffmpeg), which contains | |
| 165 | +length info. High-level functions automatically use the vbr tag if present. | |
| 166 | + | |
| 154 | 167 | ## High-level API |
| 155 | 168 | |
| 156 | −If you need only decode file/buffer, you can use optional high-level API. | |
| 169 | +If you need only decode file/buffer or use precise seek, you can use optional high-level API. | |
| 157 | 170 | Just ``#include`` ``minimp3_ex.h`` instead and use following additional functions: |
| 158 | 171 | |
| 159 | 172 | ```c |
| @@ -191,6 +204,7 @@ typedef struct · 31 unmodified lines | ||
| 191 | 204 | { |
| 192 | 205 | uint64_t samples; |
| 193 | 206 | mp3dec_frame_info_t info; |
| 207 | + int last_error; | |
| 194 | 208 | ... |
| 195 | 209 | } mp3dec_ex_t; |
| 196 | 210 | |
| @@ -234,7 +248,32 @@ MP3D_PROGRESS_CB is optional and can be NULL, example of file decoding: · 37 unmodified lines | ||
| 234 | 248 | { |
| 235 | 249 | /* error */ |
| 236 | 250 | } |
| 237 | − /* mp3dec_file_info_t contains decoded samples and info, use free(info.buffer) to deallocate samples */ | |
| 251 | + /* mp3dec_file_info_t contains decoded samples and info, | |
| 252 | + use free(info.buffer) to deallocate samples */ | |
| 253 | +``` | |
| 254 | + | |
| 255 | +Example of file decoding with seek capability: | |
| 256 | + | |
| 257 | +```c | |
| 258 | + mp3dec_ex_t dec; | |
| 259 | + if (mp3dec_ex_open(&dec, input_file_name, MP3D_SEEK_TO_SAMPLE)) | |
| 260 | + { | |
| 261 | + /* error */ | |
| 262 | + } | |
| 263 | + /* dec.samples, dec.info.hz, dec.info.layer, dec.info.channels should be filled */ | |
| 264 | + if (mp3dec_ex_seek(&dec, position)) | |
| 265 | + { | |
| 266 | + /* error */ | |
| 267 | + } | |
| 268 | + mp3d_sample_t *buffer = malloc(dec.samples*sizeof(mp3d_sample_t)); | |
| 269 | + size_t readed = mp3dec_ex_read(&dec, buffer, dec.samples); | |
| 270 | + if (readed != dec.samples) /* normal eof or error condition */ | |
| 271 | + { | |
| 272 | + if (dec.last_error) | |
| 273 | + { | |
| 274 | + /* error */ | |
| 275 | + } | |
| 276 | + } | |
| 238 | 277 | ``` |
| 239 | 278 | |
| 240 | 279 | ## Bindings |