OSSIA
Open Scenario System for Interactive Application
sound_utils.hpp
1 #pragma once
2 #include <ossia/dataflow/nodes/media.hpp>
3 #include <ossia/detail/math.hpp>
4 
5 namespace ossia
6 {
7 template <typename T>
8 static void read_audio_from_buffer(
9  const audio_span<float>& data, const int64_t start, const int64_t samples_to_write,
10  const int64_t start_offset, const int64_t loop_duration, const bool loops,
11  T** const audio_array) noexcept
12 {
13  const auto channels = data.size();
14  if(channels == 0)
15  return;
16  const int64_t file_duration = data[0].size();
17 
18  if(loops)
19  {
20  // Case where we won't loop around at all in that buffer
21  if(start + samples_to_write < loop_duration)
22  {
23  const int64_t read_start = start_offset + start;
24 
25  // Absolute best case where we can just copy directly the whole buffer
26  if(read_start + samples_to_write < file_duration)
27  {
28  for(std::size_t i = 0; i < channels; i++)
29  {
30  auto& src = data[i];
31  T* dst = audio_array[i];
32 
33  for(int64_t k = 0; k < samples_to_write; k++)
34  {
35  dst[k] = src[read_start + k];
36  }
37  }
38  }
39  else
40  {
41  // Here we must check for the end of file
42  for(std::size_t i = 0; i < channels; i++)
43  {
44  auto& src = data[i];
45  T* dst = audio_array[i];
46 
47  for(int64_t k = 0; k < samples_to_write; k++)
48  {
49  int64_t pos = read_start + k;
50  if(pos < file_duration)
51  dst[k] = src[pos];
52  else
53  dst[k] = 0;
54  }
55  }
56  }
57  }
58  else
59  {
60  // Here we may loop within that buffer
61  for(std::size_t i = 0; i < channels; i++)
62  {
63  auto& src = data[i];
64  T* dst = audio_array[i];
65 
66  for(int64_t k = 0; k < samples_to_write; k++)
67  {
68  int64_t pos = start_offset + ((start + k) % loop_duration);
69  if(pos < file_duration)
70  dst[k] = src[pos];
71  else
72  dst[k] = 0;
73  }
74  }
75  }
76  }
77  else
78  {
79  for(std::size_t i = 0; i < channels; i++)
80  {
81  const auto& src = data[i];
82  T* dst = audio_array[i];
83 
84  if(file_duration >= start + samples_to_write + start_offset)
85  {
86  // Absolute best case where we can copy the whole buffer
87  for(int64_t k = 0, pos = start + start_offset; k < samples_to_write; k++, pos++)
88  {
89  dst[k] = src[pos];
90  }
91  }
92  else
93  {
94  // This buffer will have the end of the file
95  const int64_t max = ossia::clamp(
96  file_duration - (start + start_offset), (int64_t)0, samples_to_write);
97  for(int64_t k = 0, pos = start + start_offset; k < max; k++, pos++)
98  {
99  dst[k] = src[pos];
100  }
101  for(int k = max; k < samples_to_write; k++)
102  {
103  dst[k] = 0;
104  }
105  }
106  }
107  }
108 }
109 }
Definition: git_info.h:7
constexpr OSSIA_INLINE T clamp(T d, const T min, const T max) noexcept
clamp Returns the value bounded by a min and a max
Definition: math.hpp:154
constexpr OSSIA_INLINE auto max(const T a, const U b) noexcept -> typename std::conditional<(sizeof(T) > sizeof(U)), T, U >::type
max function tailored for values
Definition: math.hpp:96