class_docstr: Inverse synthesis model (ddsp-inv).
  
  EXPERIMENTAL
  
  Builds a hierarchical model of audio:
  Audio -> Sinusoid -> Harmonic -> Sinusoid -> Audio.
  
  Unlike other models, the processor group is defined in the constructor, as
  there are many synthesizer specific regularizers and self-supervised losses.
class_docstr_tok: ["Inverse","synthesis","model","(","ddsp-inv",")",".","EXPERIMENTAL","Builds","a","hierarchical","model","of","audio",":","Audio","-",">","Sinusoid","-",">","Harmonic","-",">","Sinusoid","-",">","Audio",".","Unlike","other","models",",","the","processor","group","is","defined","in","the","constructor",",","as","there","are","many","synthesizer","specific","regularizers","and","self-supervised","losses","."]
docstr: Run forward pass of model (no losses) on a dictionary of features.
docstr_tok: ["Run","forward","pass","of","model","(","no","losses",")","on","a","dictionary","of","features","."]
code: def forward(self, features, training=True):
      """Run forward pass of model (no losses) on a dictionary of features."""
      # Audio -> Sinusoids -------------------------------------------------------
      audio = features["audio"]
  
      # Encode the data from audio to sinusoids.
      pg_in = self.sinusoidal_encoder(features, training=training)
  
      # Manually apply the scaling nonlinearities.
      sin_freqs = self.freq_scale_fn(pg_in["frequencies"])
      sin_amps = self.amps_scale_fn(pg_in["amplitudes"])
      noise_magnitudes = self.amps_scale_fn(pg_in["noise_magnitudes"])
      pg_in["frequencies"] = sin_freqs
      pg_in["amplitudes"] = sin_amps
      pg_in["noise_magnitudes"] = noise_magnitudes
  
      # Reconstruct sinusoidal audio.
      controls = self.processor_group.get_controls(pg_in)
      sin_audio = self.processor_group.get_signal(controls)
  
      outputs = {
          # Input signal.
          "audio": audio,
          # Filtered noise signal.
          "noise_magnitudes": noise_magnitudes,
          # Sinusoidal signal.
          "sin_audio": sin_audio,
          "sin_amps": sin_amps,
          "sin_freqs": sin_freqs,
      }
      outputs.update(controls)
  
      # Sinusoids -> Harmonics ---------------------------------------------------
      # Encode the sinusoids into a harmonics.
      if self.stop_gradient:
          sin_freqs = tf.stop_gradient(sin_freqs)
          sin_amps = tf.stop_gradient(sin_amps)
          noise_magnitudes = tf.stop_gradient(noise_magnitudes)
  
      if self.harmonic_encoder is not None:
          h_out = self.harmonic_encoder(sin_freqs, sin_amps)
          harm_amp, harm_dist, f0_hz = [
              h_out[k] for k in ["harm_amp", "harm_dist", "f0_hz"]
          ]
  
          # Decode harmonics back to sinusoids.
          n_harmonics = int(harm_dist.shape[-1])
          harm_freqs = ddsp.core.get_harmonic_frequencies(
              f0_hz, n_harmonics
          )
          harm_amps = harm_amp * harm_dist
  
          # Reconstruct harmonic audio.
          pg_in["frequencies"] = harm_freqs
          pg_in["amplitudes"] = harm_amps
          pg_in["noise_magnitudes"] = noise_magnitudes
          harm_audio = self.processor_group(pg_in)
  
          outputs.update(
              {
                  # Harmonic signal.
                  "harm_audio": harm_audio,
                  "harm_amp": harm_amp,
                  "harm_dist": harm_dist,
                  "f0_hz": f0_hz,
                  # Harmonic Sinusoids.
                  "harm_freqs": harm_freqs,
                  "harm_amps": harm_amps,
              }
          )
  
      return outputs
  
file_path: ddsp/ddsp/training/models/inverse_synthesis.py
imports: import functools
  import ddsp
  from ddsp.training.models.model import Model
  import tensorflow
label_desc: Use image node_id 7 for calling the InverseSynthesis obj's underlying member method code with example usage: obj.forward(features, training) and returns: outputs