| 185 | } |
| 186 | |
| 187 | void RealtimeAnalyser::getByteFrequencyData(std::vector<uint8_t> & destinationArray, bool resample) |
| 188 | { |
| 189 | if (!destinationArray.size() || !magnitudeBuffer().size()) |
| 190 | return; |
| 191 | |
| 192 | doFFTAnalysis(); |
| 193 | |
| 194 | size_t len = destinationArray.size(); |
| 195 | uint8_t * dest = &destinationArray[0]; |
| 196 | std::vector<uint8_t> result; |
| 197 | if (destinationArray.size() == frequencyBinCount()) |
| 198 | resample = false; |
| 199 | else |
| 200 | { |
| 201 | if (resample) { |
| 202 | len = frequencyBinCount(); |
| 203 | result.resize(len); |
| 204 | dest = &result[0]; |
| 205 | } |
| 206 | } |
| 207 | |
| 208 | // Convert from linear magnitude to unsigned-byte decibels. |
| 209 | size_t sourceLength = magnitudeBuffer().size(); |
| 210 | const double rangeScaleFactor = m_maxDecibels == m_minDecibels ? 1 : 1 / (m_maxDecibels - m_minDecibels); |
| 211 | const double minDecibels = m_minDecibels; |
| 212 | |
| 213 | const float * source = magnitudeBuffer().data(); |
| 214 | for (size_t i = 0; i < len; ++i) |
| 215 | { |
| 216 | float linearValue = source[i]; |
| 217 | double dbMag = !linearValue ? minDecibels : AudioUtilities::linearToDecibels(linearValue); |
| 218 | |
| 219 | // The range m_minDecibels to m_maxDecibels will be scaled to byte values from 0 to UCHAR_MAX. |
| 220 | double scaledValue = UCHAR_MAX * (dbMag - minDecibels) * rangeScaleFactor; |
| 221 | |
| 222 | // Clip to valid range. |
| 223 | if (scaledValue < 0) |
| 224 | scaledValue = 0; |
| 225 | if (scaledValue > UCHAR_MAX) |
| 226 | scaledValue = UCHAR_MAX; |
| 227 | |
| 228 | dest[i] = static_cast<unsigned char>(scaledValue); |
| 229 | } |
| 230 | if (!resample) |
| 231 | return; |
| 232 | |
| 233 | uint8_t * normalized_data = dest; |
| 234 | dest = &destinationArray[0]; |
| 235 | |
| 236 | size_t src_size = frequencyBinCount(); |
| 237 | size_t dst_size = destinationArray.size(); |
| 238 | |
| 239 | if (dst_size > src_size) |
| 240 | { |
| 241 | // upsample via linear interpolation |
| 242 | size_t steps = dst_size; |
| 243 | float u_step = 1.f / static_cast<float>(steps); |
| 244 | float u = 0; |