Multipart file uploads arrive as in-memory bytes, but the WAV decoder only reads from disk, so uploaded audio is spooled to a uniquely named temp file before decoding.
| 156 | throw std::runtime_error("audio output sample rate must be positive"); |
| 157 | } |
| 158 | if (audio.channels <= 0) { |
| 159 | throw std::runtime_error("audio output channel count must be positive"); |
| 160 | } |
| 161 | if (audio.samples.size() % static_cast<size_t>(audio.channels) != 0) { |
| 162 | throw std::runtime_error("audio output sample count must be divisible by channel count"); |
| 163 | } |
| 164 | |
| 165 | std::vector<uint8_t> out; |
| 166 | out.reserve(audio.samples.size() * sizeof(int16_t)); |
| 167 | auto append_bytes = [&](const void * data, size_t size) { |
| 168 | const auto * bytes = static_cast<const uint8_t *>(data); |
| 169 | out.insert(out.end(), bytes, bytes + size); |
| 170 | }; |
| 171 | for (float sample : audio.samples) { |
| 172 | sample = std::max(-1.0F, std::min(1.0F, sample)); |
| 173 | const auto pcm = static_cast<int16_t>(std::lrint(sample * 32767.0F)); |
| 174 | append_bytes(&pcm, sizeof(pcm)); |
| 175 | } |
| 176 | return out; |
| 177 | } |
| 178 | |
| 179 | std::string base64_encode(const uint8_t * data, size_t size) { |
| 180 | constexpr char kAlphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |