// File: /workspace/github_cpp_makefile_star2_O2/Themaister[P]umusd/alsa.cpp
// Function: ALSA::init(unsigned int, unsigned int, FF::MediaInfo::Format, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
void ALSA::init(unsigned channels, unsigned rate,
      FF::MediaInfo::Format fmt,
      const std::string &dev)
{
   stop();

   try
   {
      TRY(snd_pcm_open(&pcm, dev.c_str(), SND_PCM_STREAM_PLAYBACK, 0),
            "Failed to open device.\n");

      snd_pcm_hw_params_t *params;
      snd_pcm_hw_params_alloca(&params);

      TRY(snd_pcm_hw_params_any(pcm, params),
            "Failed to set initial params.\n");

      TRY(snd_pcm_hw_params_set_access(pcm, params,
               SND_PCM_ACCESS_RW_INTERLEAVED),
            "Failed to set RW access.\n");

      snd_pcm_format_t format;
      switch (fmt)
      {
         case FF::MediaInfo::Format::S16:
            format = SND_PCM_FORMAT_S16;
            break;
         case FF::MediaInfo::Format::S32:
            format = SND_PCM_FORMAT_S32;
            break;
         case FF::MediaInfo::Format::Float:
            format = SND_PCM_FORMAT_FLOAT;
            break;
         default:
            format = SND_PCM_FORMAT_UNKNOWN;
            break;
      }

      TRY(snd_pcm_hw_params_set_format(pcm, params,
               format),
            "Failed to set sample format.\n");

      TRY(snd_pcm_hw_params_set_channels(pcm, params,
               channels),
            "Failed to set number of channels.\n");

      TRY(snd_pcm_hw_params_set_rate(pcm, params, rate, 0),
            "Failed to set sampling rate.\n");

      unsigned usec = 500000;
      unsigned periods = 4;
      TRY(snd_pcm_hw_params_set_buffer_time_near(pcm, params,
               &usec, nullptr),
            "Failed to set buffer time.\n");

      TRY(snd_pcm_hw_params_set_periods_near(pcm, params,
               &periods, nullptr),
            "Failed to set periods.\n");

      TRY(snd_pcm_hw_params(pcm, params),
            "Failed to install params.\n");

      fds.resize(snd_pcm_poll_descriptors_count(pcm));
      snd_pcm_poll_descriptors(pcm, fds.data(), fds.size());
   }
   catch(...)
   {
      stop();
      throw;
   }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %r8, %r15
movl %ecx, %r12d
movl %edx, -0x2c(%rbp)
movl %esi, %r13d
movq %rdi, %rbx
movq (%rdi), %rax
callq *0x40(%rax)
leaq 0x30(%rbx), %r14
movq (%r15), %rsi
movq %r14, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x4240
testl %eax, %eax
js 0x4ac6
callq 0x43f0
movq %rsp, %r15
addq $0xf, %rax
andq $-0x10, %rax
subq %rax, %r15
movq %r15, %rsp
callq 0x43f0
movq %r15, %rdi
xorl %esi, %esi
movq %rax, %rdx
callq 0x4100
movq (%r14), %rdi
movq %r15, %rsi
callq 0x4150
testl %eax, %eax
js 0x4afb
movq (%r14), %rdi
pushq $0x3
popq %rdx
movq %r15, %rsi
callq 0x4300
testl %eax, %eax
js 0x4b17
decl %r12d
cmpl $0x2, %r12d
ja 0x49f4
movl %r12d, %eax
leaq 0x87c1(%rip), %rcx      # 0xd1b0
movl (%rcx,%rax,4), %edx
jmp 0x49f7
pushq $-0x1
popq %rdx
movq (%r14), %rdi
movq %r15, %rsi
callq 0x45b0
testl %eax, %eax
js 0x4b47
movq (%r14), %rdi
movq %r15, %rsi
movl %r13d, %edx
callq 0x40c0
testl %eax, %eax
js 0x4b63
movq (%r14), %rdi
movq %r15, %rsi
movl -0x2c(%rbp), %edx
xorl %ecx, %ecx
callq 0x41e0
testl %eax, %eax
js 0x4b7f
leaq -0x34(%rbp), %rdx
movl $0x7a120, (%rdx)        # imm = 0x7A120
movl $0x4, -0x30(%rbp)
movq (%r14), %rdi
movq %r15, %rsi
xorl %ecx, %ecx
callq 0x41d0
testl %eax, %eax
js 0x4baf
movq (%r14), %rdi
leaq -0x30(%rbp), %rdx
movq %r15, %rsi
xorl %ecx, %ecx
callq 0x4690
testl %eax, %eax
js 0x4bcb
movq (%r14), %rdi
movq %r15, %rsi
callq 0x44d0
testl %eax, %eax
js 0x4be7
movq 0x30(%rbx), %rdi
callq 0x4270
leaq 0x38(%rbx), %rdi
movslq %eax, %rsi
callq 0x4f06
movq 0x30(%rbx), %rdi
movq 0x38(%rbx), %rsi
movq 0x40(%rbx), %rdx
subq %rsi, %rdx
shrq $0x3, %rdx
callq 0x4170
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x10
popq %rdi
callq 0x4430
movq %rax, %r15
leaq 0x8534(%rip), %rsi      # 0xd00c
movq %rax, %rdi
callq 0x40d0
movq 0x104b9(%rip), %rsi     # 0x14fa0
movq 0x104f2(%rip), %rdx     # 0x14fe0
movq %r15, %rdi
callq 0x41c0
jmp 0x4c53
pushq $0x10
popq %rdi
callq 0x4430
movq %rax, %r15
leaq 0x8517(%rip), %rsi      # 0xd024
movq %rax, %rdi
callq 0x40d0
jmp 0x4b31
pushq $0x10
popq %rdi
callq 0x4430
movq %rax, %r15
leaq 0x851a(%rip), %rsi      # 0xd043
movq %rax, %rdi
callq 0x40d0
movq 0x10468(%rip), %rsi     # 0x14fa0
movq 0x104a1(%rip), %rdx     # 0x14fe0
movq %r15, %rdi
callq 0x41c0
pushq $0x10
popq %rdi
callq 0x4430
movq %rax, %r15
leaq 0x8504(%rip), %rsi      # 0xd05d
movq %rax, %rdi
callq 0x40d0
jmp 0x4b99
pushq $0x10
popq %rdi
callq 0x4430
movq %rax, %r15
leaq 0x8506(%rip), %rsi      # 0xd07b
movq %rax, %rdi
callq 0x40d0
jmp 0x4b99
pushq $0x10
popq %rdi
callq 0x4430
movq %rax, %r15
leaq 0x850d(%rip), %rsi      # 0xd09e
movq %rax, %rdi
callq 0x40d0
movq 0x10400(%rip), %rsi     # 0x14fa0
movq 0x10439(%rip), %rdx     # 0x14fe0
movq %r15, %rdi
callq 0x41c0
pushq $0x10
popq %rdi
callq 0x4430
movq %rax, %r15
leaq 0x84fb(%rip), %rsi      # 0xd0bc
movq %rax, %rdi
callq 0x40d0
jmp 0x4c01
pushq $0x10
popq %rdi
callq 0x4430
movq %rax, %r15
leaq 0x84fb(%rip), %rsi      # 0xd0d8
movq %rax, %rdi
callq 0x40d0
jmp 0x4c01
pushq $0x10
popq %rdi
callq 0x4430
movq %rax, %r15
leaq 0x84f7(%rip), %rsi      # 0xd0f0
movq %rax, %rdi
callq 0x40d0
movq 0x10398(%rip), %rsi     # 0x14fa0
movq 0x103d1(%rip), %rdx     # 0x14fe0
movq %r15, %rdi
callq 0x41c0
jmp 0x4c27
jmp 0x4c27
jmp 0x4c27
jmp 0x4c27
jmp 0x4c27
jmp 0x4c27
jmp 0x4c27
jmp 0x4c27
movq %rax, %r14
movq %r15, %rdi
callq 0x45c0
jmp 0x4c3d
jmp 0x4c3a
jmp 0x4c3a
jmp 0x4c3a
movq %rax, %r14
movq %r14, %rdi
callq 0x4050
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x40(%rax)
callq 0x4590
movq %rax, %rbx
callq 0x4570
movq %rbx, %rdi
callq 0x4200
movq %rax, %rdi
callq 0x4e96
nop