// File: /workspace/github_cpp_makefile_star2_O3/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 0x5240
testl %eax, %eax
js 0x5d3c
callq 0x53e0
movq %rsp, %r15
addq $0xf, %rax
andq $-0x10, %rax
subq %rax, %r15
movq %r15, %rsp
callq 0x53e0
movq %r15, %rdi
xorl %esi, %esi
movq %rax, %rdx
callq 0x50f0
movq (%r14), %rdi
movq %r15, %rsi
callq 0x5140
testl %eax, %eax
js 0x5d73
movq (%r14), %rdi
movq %r15, %rsi
movl $0x3, %edx
callq 0x52f0
testl %eax, %eax
js 0x5d91
decl %r12d
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
cmpl $0x2, %r12d
ja 0x5c6d
movl %r12d, %eax
leaq 0x95a2(%rip), %rcx      # 0xf20c
movl (%rcx,%rax,4), %edx
movq (%r14), %rdi
movq %r15, %rsi
callq 0x55e0
testl %eax, %eax
js 0x5dc3
movq (%r14), %rdi
movq %r15, %rsi
movl %r13d, %edx
callq 0x50c0
testl %eax, %eax
js 0x5de1
movq (%r14), %rdi
movq %r15, %rsi
movl -0x2c(%rbp), %edx
xorl %ecx, %ecx
callq 0x51e0
testl %eax, %eax
js 0x5dff
leaq -0x34(%rbp), %rdx
movl $0x7a120, (%rdx)        # imm = 0x7A120
movl $0x4, -0x30(%rbp)
movq (%r14), %rdi
movq %r15, %rsi
xorl %ecx, %ecx
callq 0x51d0
testl %eax, %eax
js 0x5e31
movq (%r14), %rdi
leaq -0x30(%rbp), %rdx
movq %r15, %rsi
xorl %ecx, %ecx
callq 0x56a0
testl %eax, %eax
js 0x5e4f
movq (%r14), %rdi
movq %r15, %rsi
callq 0x54e0
testl %eax, %eax
js 0x5e6d
movq 0x30(%rbx), %rdi
callq 0x5260
leaq 0x38(%rbx), %rdi
movslq %eax, %rsi
callq 0x6492
movq 0x30(%rbx), %rdi
movq 0x38(%rbx), %rsi
movq 0x40(%rbx), %rdx
subq %rsi, %rdx
shrq $0x3, %rdx
callq 0x5180
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x10, %edi
callq 0x5420
movq %rax, %r15
leaq 0x9318(%rip), %rsi      # 0xf068
movq %rax, %rdi
callq 0x50d0
movq 0x10239(%rip), %rsi     # 0x15f98
movq 0x1027a(%rip), %rdx     # 0x15fe0
movq %r15, %rdi
callq 0x51c0
jmp 0x5edb
movl $0x10, %edi
callq 0x5420
movq %rax, %r15
leaq 0x92f9(%rip), %rsi      # 0xf080
movq %rax, %rdi
callq 0x50d0
jmp 0x5dad
movl $0x10, %edi
callq 0x5420
movq %rax, %r15
leaq 0x92fa(%rip), %rsi      # 0xf09f
movq %rax, %rdi
callq 0x50d0
movq 0x101e4(%rip), %rsi     # 0x15f98
movq 0x10225(%rip), %rdx     # 0x15fe0
movq %r15, %rdi
callq 0x51c0
movl $0x10, %edi
callq 0x5420
movq %rax, %r15
leaq 0x92e2(%rip), %rsi      # 0xf0b9
movq %rax, %rdi
callq 0x50d0
jmp 0x5e1b
movl $0x10, %edi
callq 0x5420
movq %rax, %r15
leaq 0x92e2(%rip), %rsi      # 0xf0d7
movq %rax, %rdi
callq 0x50d0
jmp 0x5e1b
movl $0x10, %edi
callq 0x5420
movq %rax, %r15
leaq 0x92e7(%rip), %rsi      # 0xf0fa
movq %rax, %rdi
callq 0x50d0
movq 0x10176(%rip), %rsi     # 0x15f98
movq 0x101b7(%rip), %rdx     # 0x15fe0
movq %r15, %rdi
callq 0x51c0
movl $0x10, %edi
callq 0x5420
movq %rax, %r15
leaq 0x92d3(%rip), %rsi      # 0xf118
movq %rax, %rdi
callq 0x50d0
jmp 0x5e89
movl $0x10, %edi
callq 0x5420
movq %rax, %r15
leaq 0x92d1(%rip), %rsi      # 0xf134
movq %rax, %rdi
callq 0x50d0
jmp 0x5e89
movl $0x10, %edi
callq 0x5420
movq %rax, %r15
leaq 0x92cb(%rip), %rsi      # 0xf14c
movq %rax, %rdi
callq 0x50d0
movq 0x10108(%rip), %rsi     # 0x15f98
movq 0x10149(%rip), %rdx     # 0x15fe0
movq %r15, %rdi
callq 0x51c0
jmp 0x5eaf
jmp 0x5eaf
jmp 0x5eaf
jmp 0x5eaf
jmp 0x5eaf
jmp 0x5eaf
jmp 0x5eaf
jmp 0x5eaf
movq %rax, %r14
movq %r15, %rdi
callq 0x55f0
jmp 0x5ec5
jmp 0x5ec2
jmp 0x5ec2
jmp 0x5ec2
movq %rax, %r14
movq %r14, %rdi
callq 0x5050
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x40(%rax)
callq 0x55c0
movq %rax, %rbx
callq 0x5590
movq %rbx, %rdi
callq 0x5200
movq %rax, %rdi
callq 0x6406
nop