| 1334 | engine::debug::timing_log_scalar("stable_audio.same_decode.host.output_pack_ms", output_pack_ms); |
| 1335 | std::vector<runtime::AudioBuffer> out; |
| 1336 | out.reserve(static_cast<size_t>(batch)); |
| 1337 | for (int64_t b = 0; b < batch; ++b) { |
| 1338 | std::vector<float> interleaved(static_cast<size_t>(config.audio_channels * total_frames), 0.0F); |
| 1339 | for (int64_t frame = 0; frame < total_frames; ++frame) { |
| 1340 | for (int64_t c = 0; c < config.audio_channels; ++c) { |
| 1341 | interleaved[static_cast<size_t>(frame * config.audio_channels + c)] = |
| 1342 | channel_major[static_cast<size_t>((b * config.audio_channels + c) * total_frames + frame)]; |
| 1343 | } |
| 1344 | } |
| 1345 | out.push_back(runtime::AudioBuffer{config.sample_rate, static_cast<int>(config.audio_channels), std::move(interleaved)}); |
| 1346 | } |
| 1347 | return out; |
| 1348 | } |
| 1349 | |
| 1350 | std::vector<float> StableAudioSameRuntime::encode( |
| 1351 | const runtime::AudioBuffer & audio, |
| 1352 | int64_t audio_sample_size, |
| 1353 | uint64_t seed, |
| 1354 | uint64_t & rng_offset_blocks) const { |
| 1355 | const auto & config = assets_->config; |
| 1356 | if (audio_sample_size <= 0 || audio_sample_size % config.downsampling_ratio != 0) { |
| 1357 | throw std::runtime_error("Stable Audio SAME encode audio_sample_size is invalid"); |
| 1358 | } |
| 1359 | const auto & weights = require_same_weights(weights_, *execution_, assets_, weight_storage_type_); |
| 1360 | if (!encoder_graph_) { |
| 1361 | encoder_graph_ = std::make_unique<EncoderGraph>(*execution_, assets_, weights, weight_storage_type_); |
| 1362 | } |
| 1363 | const int64_t latent_tokens = audio_sample_size / config.downsampling_ratio; |
| 1364 | const int64_t patch_frames = audio_sample_size / config.pretransform_patch_size; |
| 1365 | auto prepared = adapt_interleaved_audio( |
| 1366 | audio, |
| 1367 | config.sample_rate, |
| 1368 | static_cast<int>(config.audio_channels), |
| 1369 | audio_sample_size); |
| 1370 | std::vector<int64_t> starts; |
| 1371 | if (latent_tokens <= kSameChunkLatents) { |
| 1372 | starts.push_back(0); |
| 1373 | } else { |
| 1374 | const int64_t hop = kSameChunkLatents - kSameChunkOverlap; |
| 1375 | for (int64_t start = 0; start <= latent_tokens - kSameChunkLatents; start += hop) { |
| 1376 | starts.push_back(start); |
| 1377 | } |
| 1378 | const int64_t final_start = latent_tokens - kSameChunkLatents; |
| 1379 | if (starts.empty() || starts.back() != final_start) { |
| 1380 | starts.push_back(final_start); |
| 1381 | } |
| 1382 | } |
| 1383 | std::vector<float> out(static_cast<size_t>(config.latent_dim * latent_tokens), 0.0F); |
| 1384 | const int64_t chunk_patch_frames = kSameChunkLatents * config.same_strides.front(); |
| 1385 | std::vector<float> token_noise; |
| 1386 | for (size_t chunk_index = 0; chunk_index < starts.size(); ++chunk_index) { |
| 1387 | const int64_t latent_start = starts[chunk_index]; |
| 1388 | const int64_t patch_start = latent_start * config.same_strides.front(); |
| 1389 | std::vector<float> patched(static_cast<size_t>(config.same_encoder_in_channels * chunk_patch_frames), 0.0F); |
| 1390 | for (int64_t l = 0; l < chunk_patch_frames; ++l) { |
| 1391 | const int64_t src_patch = patch_start + l; |
| 1392 | if (src_patch >= patch_frames) { |
| 1393 | continue; |
nothing calls this directly
no test coverage detected