OpenShot Audio Library | OpenShotAudio  0.6.0
juce_MPEValue.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2022 - Raw Material Software Limited
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 MPEValue::MPEValue() noexcept {}
27 MPEValue::MPEValue (int value) : normalisedValue (value) {}
28 
29 //==============================================================================
30 MPEValue MPEValue::from7BitInt (int value) noexcept
31 {
32  jassert (value >= 0 && value <= 127);
33 
34  auto valueAs14Bit = value <= 64 ? value << 7
35  : int (jmap<float> (float (value - 64), 0.0f, 63.0f, 0.0f, 8191.0f)) + 8192;
36 
37  return { valueAs14Bit };
38 }
39 
40 MPEValue MPEValue::from14BitInt (int value) noexcept
41 {
42  jassert (value >= 0 && value <= 16383);
43  return { value };
44 }
45 
46 MPEValue MPEValue::fromUnsignedFloat (float value) noexcept
47 {
48  jassert (0.0f <= value && value <= 1.0f);
49  return { roundToInt (value * 16383.0f) };
50 }
51 
52 MPEValue MPEValue::fromSignedFloat (float value) noexcept
53 {
54  jassert (-1.0f <= value && value <= 1.0f);
55  return { roundToInt (((value + 1.0f) * 16383.0f) / 2.0f) };
56 }
57 
58 //==============================================================================
62 
63 int MPEValue::as7BitInt() const noexcept
64 {
65  return normalisedValue >> 7;
66 }
67 
68 int MPEValue::as14BitInt() const noexcept
69 {
70  return normalisedValue;
71 }
72 
73 //==============================================================================
74 float MPEValue::asSignedFloat() const noexcept
75 {
76  return (normalisedValue < 8192)
77  ? jmap<float> (float (normalisedValue), 0.0f, 8192.0f, -1.0f, 0.0f)
78  : jmap<float> (float (normalisedValue), 8192.0f, 16383.0f, 0.0f, 1.0f);
79 }
80 
81 float MPEValue::asUnsignedFloat() const noexcept
82 {
83  return jmap<float> (float (normalisedValue), 0.0f, 16383.0f, 0.0f, 1.0f);
84 }
85 
86 //==============================================================================
87 bool MPEValue::operator== (const MPEValue& other) const noexcept
88 {
89  return normalisedValue == other.normalisedValue;
90 }
91 
92 bool MPEValue::operator!= (const MPEValue& other) const noexcept
93 {
94  return ! operator== (other);
95 }
96 
97 
98 //==============================================================================
99 //==============================================================================
100 #if JUCE_UNIT_TESTS
101 
102 class MPEValueTests final : public UnitTest
103 {
104 public:
105  MPEValueTests()
106  : UnitTest ("MPEValue class", UnitTestCategories::midi)
107  {}
108 
109  void runTest() override
110  {
111  beginTest ("comparison operator");
112  {
113  MPEValue value1 = MPEValue::from7BitInt (7);
114  MPEValue value2 = MPEValue::from7BitInt (7);
115  MPEValue value3 = MPEValue::from7BitInt (8);
116 
117  expect (value1 == value1);
118  expect (value1 == value2);
119  expect (value1 != value3);
120  }
121 
122  beginTest ("special values");
123  {
124  expectEquals (MPEValue::minValue().as7BitInt(), 0);
125  expectEquals (MPEValue::minValue().as14BitInt(), 0);
126 
127  expectEquals (MPEValue::centreValue().as7BitInt(), 64);
128  expectEquals (MPEValue::centreValue().as14BitInt(), 8192);
129 
130  expectEquals (MPEValue::maxValue().as7BitInt(), 127);
131  expectEquals (MPEValue::maxValue().as14BitInt(), 16383);
132  }
133 
134  beginTest ("zero/minimum value");
135  {
136  expectValuesConsistent (MPEValue::from7BitInt (0), 0, 0, -1.0f, 0.0f);
137  expectValuesConsistent (MPEValue::from14BitInt (0), 0, 0, -1.0f, 0.0f);
138  expectValuesConsistent (MPEValue::fromUnsignedFloat (0.0f), 0, 0, -1.0f, 0.0f);
139  expectValuesConsistent (MPEValue::fromSignedFloat (-1.0f), 0, 0, -1.0f, 0.0f);
140  }
141 
142  beginTest ("maximum value");
143  {
144  expectValuesConsistent (MPEValue::from7BitInt (127), 127, 16383, 1.0f, 1.0f);
145  expectValuesConsistent (MPEValue::from14BitInt (16383), 127, 16383, 1.0f, 1.0f);
146  expectValuesConsistent (MPEValue::fromUnsignedFloat (1.0f), 127, 16383, 1.0f, 1.0f);
147  expectValuesConsistent (MPEValue::fromSignedFloat (1.0f), 127, 16383, 1.0f, 1.0f);
148  }
149 
150  beginTest ("centre value");
151  {
152  expectValuesConsistent (MPEValue::from7BitInt (64), 64, 8192, 0.0f, 0.5f);
153  expectValuesConsistent (MPEValue::from14BitInt (8192), 64, 8192, 0.0f, 0.5f);
154  expectValuesConsistent (MPEValue::fromUnsignedFloat (0.5f), 64, 8192, 0.0f, 0.5f);
155  expectValuesConsistent (MPEValue::fromSignedFloat (0.0f), 64, 8192, 0.0f, 0.5f);
156  }
157 
158  beginTest ("value halfway between min and centre");
159  {
160  expectValuesConsistent (MPEValue::from7BitInt (32), 32, 4096, -0.5f, 0.25f);
161  expectValuesConsistent (MPEValue::from14BitInt (4096), 32, 4096, -0.5f, 0.25f);
162  expectValuesConsistent (MPEValue::fromUnsignedFloat (0.25f), 32, 4096, -0.5f, 0.25f);
163  expectValuesConsistent (MPEValue::fromSignedFloat (-0.5f), 32, 4096, -0.5f, 0.25f);
164  }
165  }
166 
167 private:
168  //==============================================================================
169  void expectValuesConsistent (MPEValue value,
170  int expectedValueAs7BitInt,
171  int expectedValueAs14BitInt,
172  float expectedValueAsSignedFloat,
173  float expectedValueAsUnsignedFloat)
174  {
175  expectEquals (value.as7BitInt(), expectedValueAs7BitInt);
176  expectEquals (value.as14BitInt(), expectedValueAs14BitInt);
177  expectFloatWithinRelativeError (value.asSignedFloat(), expectedValueAsSignedFloat, 0.0001f);
178  expectFloatWithinRelativeError (value.asUnsignedFloat(), expectedValueAsUnsignedFloat, 0.0001f);
179  }
180 
181  //==============================================================================
182  void expectFloatWithinRelativeError (float actualValue, float expectedValue, float maxRelativeError)
183  {
184  const float maxAbsoluteError = jmax (1.0f, std::abs (expectedValue)) * maxRelativeError;
185  expect (std::abs (expectedValue - actualValue) < maxAbsoluteError);
186  }
187 };
188 
189 static MPEValueTests MPEValueUnitTests;
190 
191 #endif
192 
193 } // namespace juce
float asSignedFloat() const noexcept
static MPEValue maxValue() noexcept
static MPEValue centreValue() noexcept
static MPEValue from14BitInt(int value) noexcept
bool operator==(const MPEValue &other) const noexcept
static MPEValue fromUnsignedFloat(float value) noexcept
static MPEValue fromSignedFloat(float value) noexcept
static MPEValue minValue() noexcept
float asUnsignedFloat() const noexcept
MPEValue() noexcept
int as7BitInt() const noexcept
int as14BitInt() const noexcept
static MPEValue from7BitInt(int value) noexcept
bool operator!=(const MPEValue &other) const noexcept