// File: Sleepwalking[P]world-octave/synthesis.cpp
// Function: Synthesis(double*, int, double**, double**, int, double, int, int, double*)
void Synthesis(double *f0, int f0_length, double **spectrogram,
    double **aperiodicity, int fft_size, double frame_period, int fs,
    int y_length, double *y) {
  double *impulse_response = new double[fft_size];

  for (int i = 0; i < y_length; ++i) y[i] = 0.0;

  MinimumPhaseAnalysis minimum_phase = {0};
  InitializeMinimumPhaseAnalysis(fft_size, &minimum_phase);
  InverseRealFFT inverse_real_fft = {0};
  InitializeInverseRealFFT(fft_size, &inverse_real_fft);
  ForwardRealFFT forward_real_fft = {0};
  InitializeForwardRealFFT(fft_size, &forward_real_fft);

  double *pulse_locations = new double[y_length];
  int *pulse_locations_index = new int[y_length];
  double *interpolated_vuv = new double[y_length];
  int number_of_pulses = GetTimeBase(f0, f0_length, fs, frame_period / 1000.0,
      y_length, pulse_locations, pulse_locations_index,
      interpolated_vuv);

  frame_period /= 1000.0;
  int noise_size;

  for (int i = 0; i < number_of_pulses; ++i) {
    noise_size = pulse_locations_index[MyMin(number_of_pulses - 1, i + 1)] -
      pulse_locations_index[i];

    GetOneFrameSegment(interpolated_vuv[pulse_locations_index[i]], noise_size,
        spectrogram, fft_size, aperiodicity, f0_length, frame_period,
        pulse_locations[i], fs, &forward_real_fft, &inverse_real_fft,
        &minimum_phase, impulse_response);

    int index = 0;
    for (int j = 0; j < fft_size; ++j) {
      index = MyMin(y_length - 1,
        MyMax(0, j + pulse_locations_index[i] - fft_size / 2 + 1));
        y[index] += impulse_response[j];
    }
  }

  delete[] pulse_locations;
  delete[] pulse_locations_index;
  delete[] interpolated_vuv;

  DestroyMinimumPhaseAnalysis(&minimum_phase);
  DestroyInverseRealFFT(&inverse_real_fft);
  DestroyForwardRealFFT(&forward_real_fft);

  delete[] impulse_response;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
subq $0x238, %rsp            # imm = 0x238
movq 0x18(%rbp), %rax
movl 0x10(%rbp), %eax
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movl %r8d, -0x2c(%rbp)
movsd %xmm0, -0x38(%rbp)
movl %r9d, -0x3c(%rbp)
movslq -0x2c(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x1030
movq %rax, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
cmpl 0x10(%rbp), %eax
jge 0x5062
movq 0x18(%rbp), %rax
movslq -0x4c(%rbp), %rcx
xorps %xmm0, %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x503f
leaq -0x100(%rbp), %rdi
xorl %esi, %esi
movl $0xb0, %edx
callq 0x1080
movl -0x2c(%rbp), %edi
leaq -0x100(%rbp), %rsi
callq 0x1e60
leaq -0x160(%rbp), %rdi
xorl %esi, %esi
movl $0x60, %edx
callq 0x1080
movl -0x2c(%rbp), %edi
leaq -0x160(%rbp), %rsi
callq 0x1d00
leaq -0x1c0(%rbp), %rdi
xorl %esi, %esi
movl $0x60, %edx
callq 0x1080
movl -0x2c(%rbp), %edi
leaq -0x1c0(%rbp), %rsi
callq 0x1ba0
movslq 0x10(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x1030
movq %rax, -0x1c8(%rbp)
movslq 0x10(%rbp), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x1030
movq %rax, -0x1d0(%rbp)
movslq 0x10(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x1030
movq %rax, -0x1d8(%rbp)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x3c(%rbp), %edx
movsd -0x38(%rbp), %xmm0
movsd 0x16f15(%rip), %xmm1    # 0x1c078
divsd %xmm1, %xmm0
movl 0x10(%rbp), %ecx
movq -0x1c8(%rbp), %r8
movq -0x1d0(%rbp), %r9
movq -0x1d8(%rbp), %rax
movq %rax, (%rsp)
callq 0x5400
movl %eax, -0x1dc(%rbp)
movsd -0x38(%rbp), %xmm0
movsd 0x16edd(%rip), %xmm1    # 0x1c078
divsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rbp)
movl $0x0, -0x1e4(%rbp)
movl -0x1e4(%rbp), %eax
cmpl -0x1dc(%rbp), %eax
jge 0x534b
movq -0x1d0(%rbp), %rax
movq %rax, -0x1f8(%rbp)
movl -0x1dc(%rbp), %edi
subl $0x1, %edi
movl -0x1e4(%rbp), %esi
addl $0x1, %esi
callq 0x4fb0
movl %eax, %ecx
movq -0x1f8(%rbp), %rax
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
movq -0x1d0(%rbp), %rcx
movslq -0x1e4(%rbp), %rdx
subl (%rcx,%rdx,4), %eax
movl %eax, -0x1e0(%rbp)
movq -0x1d8(%rbp), %rax
movq -0x1d0(%rbp), %rcx
movslq -0x1e4(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
movsd (%rax,%rcx,8), %xmm0
movl -0x1e0(%rbp), %edi
movq -0x20(%rbp), %rsi
movl -0x2c(%rbp), %edx
movq -0x28(%rbp), %rcx
movl -0x14(%rbp), %r8d
movsd -0x38(%rbp), %xmm1
movq -0x1c8(%rbp), %rax
movslq -0x1e4(%rbp), %r9
movsd (%rax,%r9,8), %xmm2
movl -0x3c(%rbp), %r9d
movq -0x48(%rbp), %rax
leaq -0x1c0(%rbp), %rbx
leaq -0x160(%rbp), %r11
leaq -0x100(%rbp), %r10
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq %rax, 0x18(%rsp)
callq 0x56e0
movl $0x0, -0x1e8(%rbp)
movl $0x0, -0x1ec(%rbp)
movl -0x1ec(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x5335
movl 0x10(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x1fc(%rbp)
movl -0x1ec(%rbp), %esi
movq -0x1d0(%rbp), %rax
movslq -0x1e4(%rbp), %rcx
addl (%rax,%rcx,4), %esi
movl -0x2c(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
subl %eax, %esi
addl $0x1, %esi
xorl %edi, %edi
callq 0x4f80
movl -0x1fc(%rbp), %edi
movl %eax, %esi
callq 0x4fb0
movl %eax, -0x1e8(%rbp)
movq -0x48(%rbp), %rax
movslq -0x1ec(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0x18(%rbp), %rax
movslq -0x1e8(%rbp), %rcx
addsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl -0x1ec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1ec(%rbp)
jmp 0x52a0
jmp 0x5337
movl -0x1e4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1e4(%rbp)
jmp 0x51ae
movq -0x1c8(%rbp), %rax
movq %rax, -0x208(%rbp)
cmpq $0x0, %rax
je 0x536b
movq -0x208(%rbp), %rdi
callq 0x1110
movq -0x1d0(%rbp), %rax
movq %rax, -0x210(%rbp)
cmpq $0x0, %rax
je 0x538b
movq -0x210(%rbp), %rdi
callq 0x1110
movq -0x1d8(%rbp), %rax
movq %rax, -0x218(%rbp)
cmpq $0x0, %rax
je 0x53ab
movq -0x218(%rbp), %rdi
callq 0x1110
leaq -0x100(%rbp), %rdi
callq 0x2310
leaq -0x160(%rbp), %rdi
callq 0x1dc0
leaq -0x1c0(%rbp), %rdi
callq 0x1c60
movq -0x48(%rbp), %rax
movq %rax, -0x220(%rbp)
cmpq $0x0, %rax
je 0x53ec
movq -0x220(%rbp), %rdi
callq 0x1110
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %rbp
retq
nopw %cs:(%rax,%rax)