annotate foosdk/sdk/foobar2000/helpers/input_fix_seeking.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #pragma once
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include "duration_counter.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 // Wrapper to implement input_flag_allow_inaccurate_seeking semantics with decoders that do not implement seeking properly.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 // If input_flag_allow_inaccurate_seeking is not specified, brute force seeking is used.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 template<typename base_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 class input_fix_seeking : public base_t {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 input_fix_seeking() : m_active() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 void decode_initialize(unsigned p_flags,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 base_t::decode_initialize( p_flags, p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 m_active = ( p_flags & input_flag_allow_inaccurate_seeking ) == 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 m_position = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 m_decodeFrom = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 void decode_initialize(t_uint32 p_subsong,unsigned p_flags,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 base_t::decode_initialize( p_subsong, p_flags, p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 m_active = ( p_flags & input_flag_allow_inaccurate_seeking ) == 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 m_position = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 bool decode_run(audio_chunk & p_chunk,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 if ( ! m_active ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 return base_t::decode_run ( p_chunk, p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 for ( ;; ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 if (! base_t::decode_run( p_chunk, p_abort ) ) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 double p = m_position.query();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 m_position += p_chunk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 if ( m_decodeFrom > p ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 auto skip = audio_math::time_to_samples( m_decodeFrom - p, p_chunk.get_sample_rate() );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 if ( skip >= p_chunk.get_sample_count() ) continue;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 if ( skip > 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 p_chunk.skip_first_samples( (size_t) skip );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 void decode_seek(double p_seconds,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 if ( m_active ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 if ( ! this->decode_can_seek() ) throw exception_io_object_not_seekable();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 m_decodeFrom = p_seconds;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 if ( m_decodeFrom < m_position.query() ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 base_t::decode_seek(0, p_abort); m_position.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 base_t::decode_seek(p_seconds, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 bool decode_run_raw(audio_chunk & p_chunk, mem_block_container & p_raw, abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 throw pfc::exception_not_implemented(); // shitformats that need this class are not likely to care
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 bool m_active;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 duration_counter m_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 double m_decodeFrom;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 };