foobar2000 SDK  2015-08-03
decode_postprocessor.h
Go to the documentation of this file.
7 public:
8  enum {
10  flag_eof = 1 << 0,
12  flag_altered = 1 << 1,
13  };
15  virtual bool run(dsp_chunk_list & p_chunk_list,t_uint32 p_flags,abort_callback & p_abort) = 0;
16  virtual bool get_dynamic_info(file_info & p_out) = 0;
17  virtual void flush() = 0;
18  virtual double get_buffer_ahead() = 0;
19 };
20 
25  FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(decode_postprocessor_entry)
26 public:
27  virtual bool instantiate(const file_info & info, decode_postprocessor_instance::ptr & out) = 0;
28 };
29 
30 
33 public:
34  typedef decode_postprocessor_instance::ptr item;
35  void initialize(const file_info & info) {
36  m_items.remove_all();
38  decode_postprocessor_entry::ptr ptr;
39  while(e.next(ptr)) {
40  item i;
41  if (ptr->instantiate(info, i)) m_items += i;
42  }
43  }
44  void run(dsp_chunk_list & p_chunk_list,bool p_eof,abort_callback & p_abort) {
46  for(t_size walk = 0; walk < m_items.get_size(); ++walk) {
47  if (m_items[walk]->run(p_chunk_list, flags, p_abort)) flags |= decode_postprocessor_instance::flag_altered;
48  }
49  }
50  void flush() {
51  for(t_size walk = 0; walk < m_items.get_size(); ++walk) {
52  m_items[walk]->flush();
53  }
54  }
55  static bool should_bother() {
56  return service_factory_base::is_service_present(decode_postprocessor_entry::class_guid);
57  }
58  bool is_active() const {
59  return m_items.get_size() > 0;
60  }
61  bool get_dynamic_info(file_info & p_out) {
62  bool rv = false;
63  for(t_size walk = 0; walk < m_items.get_size(); ++walk) {
64  if (m_items[walk]->get_dynamic_info(p_out)) rv = true;
65  }
66  return rv;
67  }
68  void close() {
69  m_items.remove_all();
70  }
71  double get_buffer_ahead() {
72  double acc = 0;
73  for(t_size walk = 0; walk < m_items.get_size(); ++walk) {
74  pfc::max_acc(acc, m_items[walk]->get_buffer_ahead());
75  }
76  return acc;
77  }
78 private:
80 };
81 
83 template<typename baseclass> class input_postprocessed : public baseclass {
84 public:
85  void decode_initialize(t_uint32 p_subsong,unsigned p_flags,abort_callback & p_abort) {
86  m_chunks.remove_all();
87  m_haveEOF = false;
88  m_toSkip = 0;
89  m_postproc.close();
90  if ((p_flags & input_flag_no_postproc) == 0 && m_postproc.should_bother()) {
92  this->get_info(p_subsong, info, p_abort);
93  m_postproc.initialize(info);
94  }
95  baseclass::decode_initialize(p_subsong, p_flags, p_abort);
96  }
97  void decode_initialize(unsigned p_flags,abort_callback & p_abort) {
98  m_chunks.remove_all();
99  m_haveEOF = false;
100  m_toSkip = 0;
101  m_postproc.close();
102  if ((p_flags & input_flag_no_postproc) == 0 && m_postproc.should_bother()) {
104  this->get_info(info, p_abort);
105  m_postproc.initialize(info);
106  }
107  baseclass::decode_initialize(p_flags, p_abort);
108  }
109  bool decode_run(audio_chunk & p_chunk,abort_callback & p_abort) {
110  if (m_postproc.is_active()) {
111  for(;;) {
112  p_abort.check();
113  if (m_chunks.get_count() > 0) {
114  audio_chunk * c = m_chunks.get_item(0);
115  if (m_toSkip > 0) {
116  if (!c->process_skip(m_toSkip)) {
117  m_chunks.remove_by_idx(0);
118  continue;
119  }
120  }
121  p_chunk = *c;
122  m_chunks.remove_by_idx(0);
123  return true;
124  }
125  if (m_haveEOF) return false;
126  if (!baseclass::decode_run(*m_chunks.insert_item(0), p_abort)) {
127  m_haveEOF = true;
128  m_chunks.remove_by_idx(0);
129  }
130  m_postproc.run(m_chunks, m_haveEOF, p_abort);
131  }
132  } else {
133  return baseclass::decode_run(p_chunk, p_abort);
134  }
135  }
136  bool decode_run_raw(audio_chunk & p_chunk, mem_block_container & p_raw, abort_callback & p_abort) {
137  if (m_postproc.is_active()) {
138  throw pfc::exception_not_implemented();
139  } else {
140  return baseclass::decode_run_raw(p_chunk, p_raw, p_abort);
141  }
142  }
143  bool decode_get_dynamic_info(file_info & p_out, double & p_timestamp_delta) {
144  bool rv = baseclass::decode_get_dynamic_info(p_out, p_timestamp_delta);
145  if (m_postproc.get_dynamic_info(p_out)) rv = true;
146  return rv;
147  }
148  void decode_seek(double p_seconds,abort_callback & p_abort) {
149  m_chunks.remove_all();
150  m_haveEOF = false;
151  m_postproc.flush();
152  double target = pfc::max_t<double>(0, p_seconds - m_postproc.get_buffer_ahead());
153  m_toSkip = p_seconds - target;
154  baseclass::decode_seek(target, p_abort);
155  }
156 private:
158  bool m_haveEOF;
159  double m_toSkip;
161 };
void decode_initialize(unsigned p_flags, abort_callback &p_abort)
Stream has already been altered by another instance.
Interface to a DSP chunk list. A DSP chunk list object is passed to the DSP chain each time...
Definition: dsp.h:2
Helper class for managing decode_postprocessor_instance objects. See also: input_postprocessed.
bool decode_run(audio_chunk &p_chunk, abort_callback &p_abort)
void decode_initialize(t_uint32 p_subsong, unsigned p_flags, abort_callback &p_abort)
Generic template to add decode_postprocessor support to your input class. Works with both single-trac...
decode_postprocessor_instance::ptr item
decode_postprocessor m_postproc
void info(const char *p_message)
Definition: console.cpp:4
Interface to container of a chunk of audio data. See audio_chunk_impl for an implementation.
Definition: audio_chunk.h:5
bool process_skip(double &skipDuration)
void run(dsp_chunk_list &p_chunk_list, bool p_eof, abort_callback &p_abort)
dsp_chunk_list_impl m_chunks
void max_acc(t_val &p_acc, const t_val &p_val)
Definition: primitives.h:834
virtual double get_buffer_ahead()=0
Main interface class for information about some playable object.
Definition: file_info.h:73
void initialize(const file_info &info)
bool decode_get_dynamic_info(file_info &p_out, double &p_timestamp_delta)
size_t t_size
Definition: int_types.h:48
Base class for all service classes. Provides interfaces for reference counter and querying for differ...
Definition: service.h:333
virtual bool run(dsp_chunk_list &p_chunk_list, t_uint32 p_flags, abort_callback &p_abort)=0
End of stream. Flush any buffered data during this call.
virtual bool get_dynamic_info(file_info &p_out)=0
Implements file_info.
Generic interface for a memory block; used by various other interfaces to return memory blocks while ...
FB2K_MAKE_SERVICE_INTERFACE(decode_postprocessor_instance, service_base)
static bool is_service_present(const GUID &g)
Definition: service.h:394
void decode_seek(double p_seconds, abort_callback &p_abort)
bool decode_run_raw(audio_chunk &p_chunk, mem_block_container &p_raw, abort_callback &p_abort)
bool next(service_ptr_t< t_query > &p_out)
Definition: service.h:587
pfc::list_t< item > m_items
bool get_dynamic_info(file_info &p_out)
uint32_t t_uint32
Definition: int_types.h:5