// File: Sleepwalking[P]world-octave/common.cpp
// Function: LinearSmoothing(double*, double, int, int, double*)
void LinearSmoothing(double *input, double width, int fs, int fft_size,
    double *output) {
  int boundary = static_cast<int>(width * fft_size / fs) + 1;

  // These parameters are set by the other function.
  double *mirroring_spectrum = new double[fft_size / 2 + boundary * 2 + 1];
  double *mirroring_segment = new double[fft_size / 2 + boundary * 2 + 1];
  double *frequency_axis = new double[fft_size / 2 + 1];
  SetParametersForLinearSmoothing(boundary, fft_size, fs, width,
      input, mirroring_spectrum, mirroring_segment, frequency_axis);

  double *low_levels = new double[fft_size / 2 + 1];
  double *high_levels = new double[fft_size / 2 + 1];
  double origin_of_mirroring_axis =
    -(static_cast<double>(boundary) - 0.5) * fs / fft_size;
  double discrete_frequency_interval = static_cast<double>(fs) / fft_size;

  interp1Q(origin_of_mirroring_axis, discrete_frequency_interval,
      mirroring_segment, fft_size / 2 + boundary * 2 + 1, frequency_axis,
      fft_size / 2 + 1, low_levels);

  for (int i = 0; i <= fft_size / 2; ++i) frequency_axis[i] += width;

  interp1Q(origin_of_mirroring_axis, discrete_frequency_interval,
      mirroring_segment, fft_size / 2 + boundary * 2 + 1, frequency_axis,
      fft_size / 2 + 1, high_levels);

  for (int i = 0; i <= fft_size / 2; ++i)
    output[i] = (high_levels[i] - low_levels[i]) / width;

  delete[] mirroring_spectrum;
  delete[] mirroring_segment;
  delete[] frequency_axis;
  delete[] low_levels;
  delete[] high_levels;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x8(%rbp)
movsd %xmm0, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movsd -0x10(%rbp), %xmm0
cvtsi2sdl -0x18(%rbp), %xmm1
mulsd %xmm1, %xmm0
cvtsi2sdl -0x14(%rbp), %xmm1
divsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movl -0x18(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl -0x24(%rbp), %ecx
shll %ecx
addl %ecx, %eax
addl $0x1, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x1030
movq %rax, -0x30(%rbp)
movl -0x18(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl -0x24(%rbp), %ecx
shll %ecx
addl %ecx, %eax
addl $0x1, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x1030
movq %rax, -0x38(%rbp)
movl -0x18(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
addl $0x1, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x1030
movq %rax, -0x40(%rbp)
movl -0x24(%rbp), %edi
movl -0x18(%rbp), %esi
movl -0x14(%rbp), %edx
movsd -0x10(%rbp), %xmm0
movq -0x8(%rbp), %rcx
movq -0x30(%rbp), %r8
movq -0x38(%rbp), %r9
movq -0x40(%rbp), %rax
movq %rax, (%rsp)
callq 0x1870
movl -0x18(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
addl $0x1, %eax
cltq
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 -0x18(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
addl $0x1, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x1030
movq %rax, -0x50(%rbp)
cvtsi2sdl -0x24(%rbp), %xmm0
movsd 0x1a9ce(%rip), %xmm1    # 0x1c028
subsd %xmm1, %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
cvtsi2sdl -0x14(%rbp), %xmm1
mulsd %xmm1, %xmm0
cvtsi2sdl -0x18(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rbp)
cvtsi2sdl -0x14(%rbp), %xmm0
cvtsi2sdl -0x18(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x60(%rbp)
movsd -0x58(%rbp), %xmm0
movsd -0x60(%rbp), %xmm1
movq -0x38(%rbp), %rdi
movl -0x18(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %esi
movl -0x24(%rbp), %eax
shll %eax
addl %eax, %esi
addl $0x1, %esi
movq -0x40(%rbp), %rax
movq %rax, -0x70(%rbp)
movl -0x18(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movq -0x70(%rbp), %rdx
movl %eax, %ecx
addl $0x1, %ecx
movq -0x48(%rbp), %r8
callq 0x7390
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
movl %eax, -0x74(%rbp)
movl -0x18(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0x74(%rbp), %eax
cmpl %ecx, %eax
jg 0x172c
movsd -0x10(%rbp), %xmm0
movq -0x40(%rbp), %rax
movslq -0x64(%rbp), %rcx
addsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x16f0
movsd -0x58(%rbp), %xmm0
movsd -0x60(%rbp), %xmm1
movq -0x38(%rbp), %rdi
movl -0x18(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %esi
movl -0x24(%rbp), %eax
shll %eax
addl %eax, %esi
addl $0x1, %esi
movq -0x40(%rbp), %rax
movq %rax, -0x80(%rbp)
movl -0x18(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movq -0x80(%rbp), %rdx
movl %eax, %ecx
addl $0x1, %ecx
movq -0x50(%rbp), %r8
callq 0x7390
movl $0x0, -0x68(%rbp)
movl -0x68(%rbp), %eax
movl %eax, -0x84(%rbp)
movl -0x18(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0x84(%rbp), %eax
cmpl %ecx, %eax
jg 0x17d4
movq -0x50(%rbp), %rax
movslq -0x68(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x48(%rbp), %rax
movslq -0x68(%rbp), %rcx
subsd (%rax,%rcx,8), %xmm0
divsd -0x10(%rbp), %xmm0
movq -0x20(%rbp), %rax
movslq -0x68(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x177d
movq -0x30(%rbp), %rax
movq %rax, -0x90(%rbp)
cmpq $0x0, %rax
je 0x17f1
movq -0x90(%rbp), %rdi
callq 0x1110
movq -0x38(%rbp), %rax
movq %rax, -0x98(%rbp)
cmpq $0x0, %rax
je 0x180e
movq -0x98(%rbp), %rdi
callq 0x1110
movq -0x40(%rbp), %rax
movq %rax, -0xa0(%rbp)
cmpq $0x0, %rax
je 0x182b
movq -0xa0(%rbp), %rdi
callq 0x1110
movq -0x48(%rbp), %rax
movq %rax, -0xa8(%rbp)
cmpq $0x0, %rax
je 0x1848
movq -0xa8(%rbp), %rdi
callq 0x1110
movq -0x50(%rbp), %rax
movq %rax, -0xb0(%rbp)
cmpq $0x0, %rax
je 0x1865
movq -0xb0(%rbp), %rdi
callq 0x1110
addq $0xc0, %rsp
popq %rbp
retq
nop