Skip to content

Commit e9ba379

Browse files
committed
fix vocoder shift
1 parent 8a796f7 commit e9ba379

1 file changed

Lines changed: 51 additions & 29 deletions

File tree

‎plugins/diffsinger/acoustic/AcousticInference.cpp‎

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -409,15 +409,12 @@ namespace srt::svs {
409409
std::string(param.tag.name()) +
410410
" resample failed", {}, "acoustic");
411411
}
412-
// Create f0 tensor for acoustic model
413-
auto expForAcoustic = ds::infer::inferutil::TensorHelper<float>::createFor1DArray(targetLength);
414-
if (!expForAcoustic) {
415-
Log.srtCritical("%1 start: failed to create f0 tensor: %2",
416-
kLogPrefix, expForAcoustic.error().message());
417-
return expForAcoustic.takeError();
418-
}
419-
auto &acousticHelper = expForAcoustic.value();
420-
412+
// tone_shift (音区偏移) applies to the f0 that drives the acoustic
413+
// model only. The original (un-shifted) f0 is returned through
414+
// AcousticResult::f0 so callers can drive the vocoder / variance
415+
// stage with a pitch independent from the register-shifted one;
416+
// reusing the shifted f0 there double-transposes the output.
417+
auto acousticSamples = samples;
421418
if (pToneShiftParam) {
422419
const auto &toneShift = *pToneShiftParam;
423420
if (!toneShift.values.empty()) {
@@ -430,35 +427,60 @@ namespace srt::svs {
430427
}
431428
if (convertToF0) {
432429
for (size_t i = 0; i < targetLength; ++i) {
433-
samples[i] += toneShiftSamples[i] / 100.0;
430+
acousticSamples[i] += toneShiftSamples[i] / 100.0;
434431
}
435432
} else {
436433
for (size_t i = 0; i < targetLength; ++i) {
437-
samples[i] *= std::exp2(toneShiftSamples[i] / 1200.0);
434+
acousticSamples[i] *= std::exp2(toneShiftSamples[i] / 1200.0);
438435
}
439436
}
440437
}
441438
}
442-
if (convertToF0) {
443-
// Convert midi note to hz
444-
for (const auto midi_note : std::as_const(samples)) {
445-
constexpr double a4_freq_hz = 440.0;
446-
constexpr double midi_a4_note = 69.0;
447-
const auto f0Acoustic =
448-
a4_freq_hz * std::exp2((midi_note - midi_a4_note) / 12.0);
449-
// Buffer guaranteed not to overflow,
450-
// given (resampled.size() == targetLength), which has been checked before
451-
acousticHelper.writeUnchecked(static_cast<float>(f0Acoustic));
452-
}
453-
} else {
454-
for (const auto sample : std::as_const(samples)) {
455-
// Buffer guaranteed not to overflow,
456-
// given (resampled.size() == targetLength), which has been checked before
457-
acousticHelper.writeUnchecked(static_cast<float>(sample));
439+
440+
// Convert midi note to hz
441+
const auto toHz = [](double note) -> float {
442+
constexpr double a4_freq_hz = 440.0;
443+
constexpr double midi_a4_note = 69.0;
444+
return static_cast<float>(a4_freq_hz * std::exp2((note - midi_a4_note) / 12.0));
445+
};
446+
const auto fillF0 = [&](ds::infer::inferutil::TensorHelper<float> &helper,
447+
const std::vector<double> &value) {
448+
if (convertToF0) {
449+
for (const auto item : std::as_const(value)) {
450+
// Buffer guaranteed not to overflow,
451+
// given samples.size() == targetLength, checked above
452+
helper.writeUnchecked(toHz(item));
453+
}
454+
} else {
455+
for (const auto item : std::as_const(value)) {
456+
// Buffer guaranteed not to overflow,
457+
// given samples.size() == targetLength, checked above
458+
helper.writeUnchecked(static_cast<float>(item));
459+
}
458460
}
461+
};
462+
463+
// f0 tensor for the acoustic model (tone-shifted)
464+
auto expForAcoustic = ds::infer::inferutil::TensorHelper<float>::createFor1DArray(targetLength);
465+
if (!expForAcoustic) {
466+
Log.srtCritical("%1 start: failed to create f0 tensor: %2",
467+
kLogPrefix, expForAcoustic.error().message());
468+
return expForAcoustic.takeError();
459469
}
460-
f0TensorForVocoder = acousticHelper.take();
461-
sessionInput->inputs["f0"] = f0TensorForVocoder; // ref count +1
470+
auto &acousticHelper = expForAcoustic.value();
471+
fillF0(acousticHelper, acousticSamples);
472+
sessionInput->inputs["f0"] = acousticHelper.take(); // ref count +1
473+
474+
// f0 tensor for the vocoder (original, un-shifted)
475+
auto expForVocoder = ds::infer::inferutil::TensorHelper<float>::createFor1DArray(targetLength);
476+
if (!expForVocoder) {
477+
Log.srtCritical("%1 start: failed to create vocoder f0 tensor: %2",
478+
kLogPrefix, expForVocoder.error().message());
479+
return expForVocoder.takeError();
480+
}
481+
auto &vocoderHelper = expForVocoder.value();
482+
fillF0(vocoderHelper, samples);
483+
f0TensorForVocoder = vocoderHelper.take();
462484
return srt::core::Expected<void>();
463485
};
464486

0 commit comments

Comments
 (0)