33 (
static_cast<int>(sample) - 128) * 256);
38 const int value =
static_cast<int>(sample) / 256 + 128;
39 return static_cast<std::uint8_t
>(std::clamp(
value, 0, 255));
45 if (event.format.formatTag !=
FormatTag ||
46 event.format.channels != 1u ||
50 event.format.bitsPerSample != 0u ||
51 event.format.extraSize < 2u ||
52 event.payload.size() < 20u)
80 return impl_ && impl_->state !=
nullptr;
86 impl_ = std::make_unique<Impl>();
89 std::expected<std::vector<std::uint8_t>, std::string>
92 if (!impl_ || impl_->state ==
nullptr)
93 return std::unexpected(
"libgsm WAV49 encoder is unavailable");
95 pending_.insert(pending_.end(), pcm.begin(), pcm.end());
97 std::vector<std::uint8_t>
encoded;
100 std::array<gsm_signal, SamplesPerFrame>
samples{};
101 std::array<gsm_byte, 33>
frame{};
119 pending_.erase(pending_.begin(), pending_.begin() +
120 static_cast<std::ptrdiff_t
>(
offset));
130 if (
state !=
nullptr)
146 return impl_ && impl_->state !=
nullptr;
151 impl_ = std::make_unique<Impl>();
154 std::expected<std::vector<std::uint8_t>, std::string>
157 if (!impl_ || impl_->state ==
nullptr)
158 return std::unexpected(
"libgsm WAV49 decoder is unavailable");
160 return std::unexpected(
"GSM 6.10 payload is not block aligned");
162 std::vector<std::uint8_t> pcm;
164 std::array<gsm_signal, SamplesPerFrame>
samples{};
171 return std::unexpected(
"invalid first GSM 6.10 WAV49 frame");
172 for (
const auto sample :
samples)
173 pcm.push_back(
toU8(sample));
175 auto* second =
const_cast<gsm_byte*
>(
178 return std::unexpected(
"invalid second GSM 6.10 WAV49 frame");
179 for (
const auto sample :
samples)
180 pcm.push_back(
toU8(sample));
std::expected< std::vector< std::uint8_t >, std::string > decodeToU8(std::span< const std::uint8_t > encoded)
std::expected< std::vector< std::uint8_t >, std::string > encodeU8(std::span< const std::uint8_t > pcm)
constexpr std::uint16_t SamplesPerBlock
constexpr std::uint32_t SampleRate
constexpr std::uint16_t FormatTag
constexpr std::uint16_t BlockAlign
constexpr std::uint32_t AverageBytesPerSecond
constexpr std::uint16_t SamplesPerFrame
bool matchesRetailWireFormat(const packet::Event &event) noexcept
std::uint16_t readLe16(std::span< const std::uint8_t > bytes, std::size_t offset) noexcept