SAL
A C++ library for spatial audio.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
delayfilter.h
Go to the documentation of this file.
1 /*
2  delayfilter.h
3  Spatial Audio Library (SAL)
4  Copyright (c) 2011, Enzo De Sena
5  All rights reserved.
6 
7  Authors: Enzo De Sena, enzodesena@gmail.com
8 
9  */
10 
11 #ifndef SAL_DELAYFILTER_H
12 #define SAL_DELAYFILTER_H
13 
14 #define DEFAULT_MAX_LATENCY 3276800
15 
16 #include "saltypes.h"
17 #include "digitalfilter.h"
18 #include "salconstants.h"
19 #include <algorithm>
20 
21 namespace sal {
22 
23 class DelayFilter : public mcl::DigitalFilter {
24 
25 public:
31  DelayFilter(const Int latency, Int max_latency) noexcept;
32 
33  ~DelayFilter() noexcept { delete[] start_; }
34 
39  inline void Write(const Sample sample) noexcept { *write_index_ = sample; }
40 
41  void Write(const Sample* samples, const Int num_samples) noexcept;
42 
44  virtual void Reset() noexcept;
45 
50  inline Sample Read() const noexcept { return *read_index_; }
51 
53  inline const Sample& ReadAt(const Int delay_tap) const noexcept {
54 #ifndef NOLOGGING
55  if (delay_tap > max_latency_) {
56  mcl::Logger::GetInstance().
57  LogError("Trying to read at a delay tap (%d) larger than the maximum latency "
58  "of the delay line (%d). Giving back the value at the maximum "
59  "latency instead. ",
60  delay_tap, max_latency_);
61  }
62 #endif
63 
64  ASSERT(write_index_>= start_ && write_index_ <= end_);
65  Sample* read_index = write_index_ - std::min(delay_tap, max_latency_);
66  return (read_index >= start_) ? *read_index : *(read_index + max_latency_ + 1);
67  }
68 
72  void Read(const Int num_samples, Sample* output_data) const noexcept;
73 
74  inline Sample FractionalReadAt(const Time fractional_delay_tap) const noexcept {
75 #ifndef NOLOGGING
76  if (fractional_delay_tap >= (Time) max_latency_) {
77  mcl::Logger::GetInstance().
78  LogError("Trying to read at a delay tap (%f) larger than the maximum latency "
79  "of the delay line (%d). Giving back the value at the maximum "
80  "latency instead. ",
81  fractional_delay_tap, max_latency_);
82  }
83 #endif
84 
85  Time sanitised_delay_tap = std::min(fractional_delay_tap, (Time) max_latency_);
86  Int x_a = (Int) sanitised_delay_tap; // Cast to int is equivalent to floor
87  Int x_b = x_a + 1;
88  Sample f_x_a = ReadAt(x_a);
89  Sample f_x_b = ReadAt(x_b);
90  return (f_x_b-f_x_a)/(x_b-x_a)*(sanitised_delay_tap-x_a)+f_x_a;
91  }
92 
94  inline void Tick() noexcept {
97  }
98 
101  void Tick(const Int num_samples) noexcept;
102 
107  void SetLatency(const Int) noexcept;
108 
110  Int latency() const noexcept;
111 
113  Int max_latency() const noexcept;
114 
115  DelayFilter& operator= (const DelayFilter&);
116  DelayFilter (const DelayFilter&);
117 
118  virtual mcl::Real Filter(const mcl::Real input) noexcept;
119 
120  static bool Test();
121 protected:
126  sal::Int latency_;
128 };
129 
130 } // namespace sal
131 
132 #endif