// File: mikeakohn[P]drumsplusplus/build/../src/Song.cxx
// Function: Song::play_pattern(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)
void Song::play_pattern(std::string &pattern_name)
{
  int index, count;
  uint8_t midi_data[256];
  Note note;
  uint32_t k;
  uint32_t r;
#ifdef WINDOWS
  int n;
#endif

  Pattern &pattern = patterns[pattern_name];

  if (interactive == 1)
  {
    printf("Pattern: %s", pattern_name.c_str());
  }

#ifdef DEBUG
printf("  Playing pattern %s\n", pattern_name.c_str());
printf("[ ");
#endif

  k = 0;
  count = pattern.get_count();

  for (index = 0; index < count; index++)
  {
    Pattern::Data &data = pattern.get_data(index);

#ifdef DEBUG
printf("%x %x %x, ", 0x90 + data.channel, data.value, data.volume);
#endif

    if (!midi_file->is_open())
    {
      midi_data[k++] = 0x90 + data.channel;
      midi_data[k++] = data.value;
      midi_data[k++] = data.volume;

      if (data.duration != 0)
      {
        midi_player->play(midi_data, k);

        for (r = 0; r < k; r++)
        {
          printf(" %02x\n", midi_data[r]);
        }

#ifdef DEBUG
printf("usleep(%d) ", data.duration);
#endif

#ifndef WINDOWS
        if (play_timer.it_value.tv_sec == 0 && play_timer.it_value.tv_usec == 0)
        {
          usleep(data.duration);
        }
          else
        {
          getitimer(ITIMER_PROF, &play_timer);

          if (play_timer.it_value.tv_usec != 0)
          {
            r = play_timer.it_value.tv_usec;
          }
            else
          {
            r = 0;
          }

          if (r > data.duration) { r = data.duration; }
#ifdef DEBUG
printf("currtime %ld %ld\n",
  play_timer.it_value.tv_sec,
  play_timer.it_value.tv_usec);
printf("interval %ld %ld\n",
  play_timer.it_interval.tv_sec,
  play_timer.it_interval.tv_usec);
printf("%d %d\n", data.duration, r);
#endif
          usleep(data.duration -
                 (((20 - play_timer.it_value.tv_sec) * 1000000) + r));
        }

        play_timer.it_value.tv_sec = 20;
        play_timer.it_value.tv_usec = 0;

        /* setitimer(ITIMER_REAL,&play_timer, 0); */
        setitimer(ITIMER_PROF,&play_timer, 0);
#else
        if (play_timer == 0)
        {
          Sleep(data.duration / 1000);
        }
          else
        {
          Sleep((data.duration / 1000) - (timeGetTime() - play_timer));
        }

        play_timer = timeGetTime();
#endif
        k = 0;
      }
    }
      else
    {
      note.value = data.value;
      note.volume = data.volume;
      note.duration = data.duration;
      note.midi_channel = data.channel;

      midi_file->write_note(&song_info, &note);
    }

    //ptr++;
  }

#ifdef DEBUG
printf(" ]\n");
#endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x150(%rbp)
addq $0x78, %rdi
movq -0x10(%rbp), %rsi
callq 0x8cf0
movq %rax, %rcx
movq -0x150(%rbp), %rax
movq %rcx, -0x140(%rbp)
cmpl $0x1, 0x128(%rax)
jne 0x861f
movq -0x10(%rbp), %rdi
callq 0x2100
movq %rax, %rsi
leaq 0x8367(%rip), %rdi      # 0x1097f
movb $0x0, %al
callq 0x2060
movl $0x0, -0x134(%rbp)
movq -0x140(%rbp), %rdi
callq 0x9510
movl %eax, -0x18(%rbp)
movl $0x0, -0x14(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x88e0
movq -0x140(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x9530
movq %rax, %rcx
movq -0x150(%rbp), %rax
movq %rcx, -0x148(%rbp)
movq 0x38(%rax), %rdi
callq 0x29d0
testb $0x1, %al
jne 0x8878
movq -0x148(%rbp), %rax
movzbl 0x2(%rax), %eax
addl $0x90, %eax
movb %al, %cl
movl -0x134(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x134(%rbp)
movl %eax, %eax
movb %cl, -0x120(%rbp,%rax)
movq -0x148(%rbp), %rax
movb (%rax), %cl
movl -0x134(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x134(%rbp)
movl %eax, %eax
movb %cl, -0x120(%rbp,%rax)
movq -0x148(%rbp), %rax
movb 0x1(%rax), %cl
movl -0x134(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x134(%rbp)
movl %eax, %eax
movb %cl, -0x120(%rbp,%rax)
movq -0x148(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0x8876
movq -0x150(%rbp), %rax
movq 0x40(%rax), %rdi
leaq -0x120(%rbp), %rsi
movl -0x134(%rbp), %edx
callq 0x37d0
movl $0x0, -0x138(%rbp)
movl -0x138(%rbp), %eax
cmpl -0x134(%rbp), %eax
jae 0x8762
movl -0x138(%rbp), %eax
movzbl -0x120(%rbp,%rax), %esi
leaq 0x8241(%rip), %rdi      # 0x1098b
movb $0x0, %al
callq 0x2060
movl -0x138(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x138(%rbp)
jmp 0x8727
movq -0x150(%rbp), %rax
cmpq $0x0, 0x118(%rax)
jne 0x8798
movq -0x150(%rbp), %rax
cmpq $0x0, 0x120(%rax)
jne 0x8798
movq -0x148(%rbp), %rax
movl 0x4(%rax), %edi
callq 0x2330
jmp 0x883a
movq -0x150(%rbp), %rsi
addq $0x108, %rsi            # imm = 0x108
movl $0x2, %edi
callq 0x23b0
movq -0x150(%rbp), %rax
cmpq $0x0, 0x120(%rax)
je 0x87d7
movq -0x150(%rbp), %rax
movq 0x120(%rax), %rax
movl %eax, -0x138(%rbp)
jmp 0x87e1
movl $0x0, -0x138(%rbp)
movl -0x138(%rbp), %eax
movq -0x148(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jbe 0x8803
movq -0x148(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x138(%rbp)
movq -0x150(%rbp), %rdx
movq -0x148(%rbp), %rax
movl 0x4(%rax), %eax
movl $0x14, %ecx
subq 0x118(%rdx), %rcx
imulq $0xf4240, %rcx, %rcx    # imm = 0xF4240
movl -0x138(%rbp), %edx
addq %rdx, %rcx
subq %rcx, %rax
movl %eax, %edi
callq 0x2330
movq -0x150(%rbp), %rsi
movq $0x14, 0x118(%rsi)
movq $0x0, 0x120(%rsi)
addq $0x108, %rsi            # imm = 0x108
movl $0x2, %edi
xorl %eax, %eax
movl %eax, %edx
callq 0x2370
movl $0x0, -0x134(%rbp)
jmp 0x88d0
movq -0x150(%rbp), %rsi
movq -0x148(%rbp), %rax
movb (%rax), %al
movb %al, -0x130(%rbp)
movq -0x148(%rbp), %rax
movzbl 0x1(%rax), %eax
movl %eax, -0x12c(%rbp)
movq -0x148(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x128(%rbp)
movq -0x148(%rbp), %rax
movzbl 0x2(%rax), %eax
movl %eax, -0x124(%rbp)
movq 0x38(%rsi), %rdi
leaq -0x130(%rbp), %rdx
callq 0x3330
jmp 0x88d2
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x863f
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
nopl (%rax)