OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
float_to_sample.hpp
1#pragma once
2
3#include <ossia/dataflow/nodes/media.hpp>
5
6#include <cstdint>
7#include <limits>
8
9namespace ossia
10{
28template <typename SampleFormat, int N>
29constexpr SampleFormat float_to_sample(ossia::audio_sample sample) noexcept;
30
31template <>
32constexpr uint8_t float_to_sample<uint8_t, 8>(ossia::audio_sample sample) noexcept
33{
34 // 0 -> 255 to -1 -> 1
35 if constexpr(std::is_same_v<ossia::audio_sample, float>)
36 {
37 return (sample + 1.f) * 127.5f;
38 }
39 else
40 {
41 return (sample + 1.) * 127.5;
42 }
43}
44
45template <>
46constexpr int16_t float_to_sample<int16_t, 16>(ossia::audio_sample sample) noexcept
47{
48 // TODO division -> multiplication
49 if constexpr(std::is_same_v<ossia::audio_sample, float>)
50 {
51 return sample * (0x7FFF + .5f) - 0.5f;
52 }
53 else
54 {
55 return sample * (0x7FFF + .5) - 0.5;
56 }
57}
58
59// ALSA S24_LE: https://stackoverflow.com/a/40301874/1495627
60template <>
61constexpr int32_t float_to_sample<int32_t, 24>(ossia::audio_sample x) noexcept
62{
63 if constexpr(std::is_same_v<ossia::audio_sample, float>)
64 {
65 return (x * (0x7FFFFF + 0.5f)) - 0.5f;
66 }
67 else
68 {
69 return (x * (0x7FFFFF + 0.5)) - 0.5;
70 }
71}
72
73template <>
74constexpr int32_t float_to_sample<int32_t, 32>(audio_sample x) noexcept
75{
76 // In double even when the samples are float: 0x7FFFFFFF + 0.5 is not
77 // representable as a float and rounds to 2^31, which +1.0 then converts out
78 // of int32_t's range.
79 return (double(x) * (0x7FFFFFFF + 0.5)) - 0.5;
80}
81
82template <>
83constexpr float float_to_sample<float, 32>(float sample) noexcept
84{
85 return sample;
86}
87
88#if defined(_MSC_VER)
89#define OSSIA_RESTRICT __restrict
90#else
91#define OSSIA_RESTRICT __restrict__
92#endif
93
94template <typename SampleFormat, int N, int ByteIncrement, typename InputFormat>
95 requires(sizeof(SampleFormat) == ByteIncrement)
96inline void interleave(
97 const InputFormat* const* OSSIA_RESTRICT in, SampleFormat* OSSIA_RESTRICT out,
98 int channels, int bs)
99{
100 for(int c = 0; c < channels; c++)
101 {
102 auto* in_channel = in[c];
103 for(int k = 0; k < bs; k++)
104 {
105 out[k * channels + c] = float_to_sample<SampleFormat, N>(in_channel[k]);
106 }
107 }
108}
109
110template <typename SampleFormat, int N, int ByteIncrement, typename InputFormat>
111 requires(sizeof(SampleFormat) != ByteIncrement)
112inline void interleave(
113 const InputFormat* const* OSSIA_RESTRICT in, SampleFormat* out, int channels, int bs)
114{
115 for(int c = 0; c < channels; c++)
116 {
117 auto* in_channel = in[c];
118 for(int k = 0; k < bs; k++)
119 {
120 // Case packed 24-bit: we have to go through raw char*
121 char* out_raw = reinterpret_cast<char*>(out);
122 auto mem
123 = reinterpret_cast<SampleFormat*>(out_raw[(k * channels + c) * ByteIncrement]);
124 *mem = float_to_sample<SampleFormat, N>(in_channel[k]);
125 }
126 }
127}
128
129template <typename SampleFormat, int N, typename InputFormat>
130inline void convert(
131 const InputFormat* const* OSSIA_RESTRICT in, SampleFormat* OSSIA_RESTRICT out,
132 int channels, int bs)
133{
134 for(int c = 0; c < channels; c++)
135 {
136 auto* in_channel = in[c];
137 auto* out_channel = out + c * bs;
138 for(int k = 0; k < bs; k++)
139 {
140 out_channel[k] = float_to_sample<SampleFormat, N>(in_channel[k]);
141 }
142 }
143}
144}
Definition git_info.h:7
constexpr SampleFormat float_to_sample(ossia::audio_sample sample) noexcept