// File: mindbeast[P]rnes/apu.cpp
// Function: Rnes::Apu::generateSample()
void Apu::generateSample() {
  // float sample = (samples[sampleOffset % sampleBufferSize] + samples[(sampleOffset - 32) %
  // sampleBufferSize]) / 2;
  float sample = 0.0f;
  sample += 0.02051777 * (samples[sampleOffset % sampleBufferSize]);
  sample += 0.06532911 * (samples[(sampleOffset - 1) % sampleBufferSize]);
  sample += 0.16640572 * (samples[(sampleOffset - 2) % sampleBufferSize]);
  sample += 0.2477474 * (samples[(sampleOffset - 3) % sampleBufferSize]);
  sample += 0.2477474 * (samples[(sampleOffset - 4) % sampleBufferSize]);
  sample += 0.16640572 * (samples[(sampleOffset - 5) % sampleBufferSize]);
  sample += 0.06532911 * (samples[(sampleOffset - 6) % sampleBufferSize]);
  sample += 0.02051777 * (samples[(sampleOffset - 7) % sampleBufferSize]);

  int16_t truncSample = (int16_t)((sample) * (1 << 14));

  const unsigned int bufferedSamples = 32;
  sampleBuffer.push_back(truncSample);
  if (sampleBuffer.size() == bufferedSamples) {
    rb->putData(sampleBuffer.data(), bufferedSamples);
    sampleBuffer.clear();
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x20(%rbp)
movl $0x0, -0xc(%rbp)
movl 0xb0(%rdi), %eax
andl $0x1f, %eax
movss 0x2c(%rdi,%rax,4), %xmm0
cvtss2sd %xmm0, %xmm0
movss -0xc(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
movsd 0x43359(%rip), %xmm2    # 0x69428
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0xc(%rbp)
movl 0xb0(%rdi), %eax
decl %eax
andl $0x1f, %eax
movss 0x2c(%rdi,%rax,4), %xmm0
cvtss2sd %xmm0, %xmm0
movss -0xc(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
movsd 0x4332a(%rip), %xmm3    # 0x69430
mulsd %xmm3, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0xc(%rbp)
movl 0xb0(%rdi), %eax
addl $-0x2, %eax
andl $0x1f, %eax
movss 0x2c(%rdi,%rax,4), %xmm0
cvtss2sd %xmm0, %xmm0
movss -0xc(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
movsd 0x432fa(%rip), %xmm4    # 0x69438
mulsd %xmm4, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0xc(%rbp)
movl 0xb0(%rdi), %eax
addl $-0x3, %eax
andl $0x1f, %eax
movss 0x2c(%rdi,%rax,4), %xmm0
cvtss2sd %xmm0, %xmm0
movss -0xc(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
movsd 0x432ca(%rip), %xmm5    # 0x69440
mulsd %xmm5, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0xc(%rbp)
movl 0xb0(%rdi), %eax
addl $-0x4, %eax
andl $0x1f, %eax
movss 0x2c(%rdi,%rax,4), %xmm0
cvtss2sd %xmm0, %xmm0
movss -0xc(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm5, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0xc(%rbp)
movl 0xb0(%rdi), %eax
addl $-0x5, %eax
andl $0x1f, %eax
movss 0x2c(%rdi,%rax,4), %xmm0
cvtss2sd %xmm0, %xmm0
movss -0xc(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm4, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0xc(%rbp)
movl 0xb0(%rdi), %eax
addl $-0x6, %eax
andl $0x1f, %eax
movss 0x2c(%rdi,%rax,4), %xmm0
cvtss2sd %xmm0, %xmm0
movss -0xc(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm3, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0xc(%rbp)
movl 0xb0(%rdi), %eax
addl $-0x7, %eax
andl $0x1f, %eax
movss 0x2c(%rdi,%rax,4), %xmm0
cvtss2sd %xmm0, %xmm0
movss -0xc(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0xc(%rbp)
movss -0xc(%rbp), %xmm0
movss 0x431f4(%rip), %xmm1    # 0x69448
mulss %xmm1, %xmm0
cvttss2si %xmm0, %eax
movw %ax, -0xe(%rbp)
movl $0x20, -0x14(%rbp)
addq $0x118, %rdi            # imm = 0x118
movw -0xe(%rbp), %ax
movw %ax, -0x16(%rbp)
leaq -0x16(%rbp), %rsi
callq 0x27440
movq -0x20(%rbp), %rdi
addq $0x118, %rdi            # imm = 0x118
callq 0x27470
cmpq $0x20, %rax
jne 0x262da
movq -0x20(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0x27490
movq -0x20(%rbp), %rdi
movq %rax, -0x28(%rbp)
addq $0x118, %rdi            # imm = 0x118
callq 0x275c0
movq -0x28(%rbp), %rdi
movq %rax, %rsi
movl $0x20, %edx
callq 0x274b0
movq -0x20(%rbp), %rdi
addq $0x118, %rdi            # imm = 0x118
callq 0x275e0
addq $0x30, %rsp
popq %rbp
retq